摘要:新的數(shù)據(jù)表關(guān)系數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)類似于這樣子大碼中碼小碼這個(gè)表結(jié)構(gòu)的說(shuō)明是避免對(duì)于關(guān)系鏈的數(shù)據(jù)邏輯不理解做的一個(gè)示例。
最近幾天一直在糾結(jié)于一個(gè)大數(shù)據(jù)批量導(dǎo)入的問(wèn)題,經(jīng)過(guò)幾天思考,發(fā)現(xiàn)基于小數(shù)據(jù)情況,原本的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)是沒(méi)有問(wèn)題的,但是在大量數(shù)據(jù)導(dǎo)入,問(wèn)題就很大了。我之前一直在強(qiáng)調(diào)“程序=數(shù)據(jù)結(jié)構(gòu)+算法”,但在這此卻鉆了牛角尖,最后去仔細(xì)看了之前別人設(shè)計(jì)的數(shù)據(jù)表才突然靈光一現(xiàn),發(fā)現(xiàn)了mysql層面要以空間換時(shí)間的具體設(shè)計(jì)思路。
基于這種情況,先說(shuō)一下經(jīng)過(guò)這個(gè)過(guò)程后的感悟。
感悟后續(xù)的程序邏輯如果出現(xiàn)算法復(fù)雜的問(wèn)題,不要延續(xù)之前的程序設(shè)計(jì),同樣不要延續(xù)之前的數(shù)據(jù)表結(jié)構(gòu)設(shè)計(jì),要多方面思考。
隨著業(yè)務(wù)的變更,不僅僅是程序上的變更,還有數(shù)據(jù)結(jié)構(gòu)上的變更,大量數(shù)據(jù)的處理方式與常規(guī)處理數(shù)據(jù)思維不太一樣。
產(chǎn)品需求這次的具體問(wèn)題,我先從產(chǎn)品需求說(shuō)起,并從頭聊我踩過(guò)的坑。
用戶撒碼可以根據(jù)這個(gè)碼知道商品流向,系統(tǒng)有幾層代理商,在商品到達(dá)用戶手中之后,用戶可以根據(jù)掃碼查詢整個(gè)商品的流向,經(jīng)過(guò)了哪些代理商手中;
代理商掃碼可以進(jìn)行發(fā)貨,根據(jù)這個(gè)追溯碼標(biāo)記商品發(fā)貨狀態(tài),同時(shí)存儲(chǔ)代理商發(fā)貨狀態(tài)。
追溯碼有三個(gè)碼類,分為大碼、中碼、小碼,類似于一個(gè)大碼對(duì)應(yīng)一箱貨物,一個(gè)中碼對(duì)應(yīng)一箱貨物中的一盒,一個(gè)小碼對(duì)應(yīng)一盒貨物中的某一件具體貨物;也就是說(shuō)大碼涵蓋中碼,中碼涵蓋小碼,需要通過(guò)上層的追溯碼找到整個(gè)關(guān)系鏈。
商戶根據(jù)需要,進(jìn)行追溯碼導(dǎo)入,一次性導(dǎo)入的數(shù)據(jù)條數(shù)大約為10萬(wàn)條左右,也可能更多,也可能更少。
踩坑 原本的數(shù)據(jù)表結(jié)構(gòu)設(shè)計(jì)admin_id #商戶ID product_id #商品ID security_code #追溯碼 code_type #追溯碼類型:1大碼,2中碼,3小碼 parent_id #當(dāng)前追溯碼的上級(jí)ID,如小碼對(duì)應(yīng)的上級(jí)中碼ID top_id #頂級(jí)ID,對(duì)應(yīng)的為大碼的ID,中碼和小碼都要村粗 is_use #此追溯碼是否已使用 is_sell_out #是否已經(jīng)售出 created_time #創(chuàng)建時(shí)間 updated_time #更新時(shí)間 is_deleted #是否刪除原程序設(shè)計(jì)思想
整套數(shù)據(jù)表結(jié)構(gòu)的設(shè)計(jì)邏輯是以 parent_id 來(lái)進(jìn)行關(guān)系關(guān)聯(lián),然后通過(guò)code_type來(lái)標(biāo)明追溯碼的類型,在導(dǎo)入的時(shí)候,先必須村粗父級(jí),然后再存儲(chǔ)子級(jí),層層遍歷導(dǎo)入。
此設(shè)計(jì)產(chǎn)生的問(wèn)題由于必須層層遍歷導(dǎo)入,就會(huì)造成導(dǎo)入相當(dāng)緩慢,必須先插入富級(jí)ID,然后再插入子級(jí)ID,因?yàn)樽蛹?jí)ID關(guān)聯(lián)了父級(jí)ID。這樣也就不能采用mysql的
INSERT INTO table(field1,field2) VALUES("a", 1), ("b", 1), ("c", 1);
這種批量插入的方式進(jìn)行插入,這樣的話,數(shù)據(jù)插入就會(huì)很緩慢。
經(jīng)過(guò)我后面的思考,把最后一級(jí),也就是小碼采用了批量插入,但是發(fā)現(xiàn)效率還是并不高,就算把小碼改為批量插入,一次性批量插入的數(shù)據(jù)也僅有20條左右,對(duì)效率提高并不大。
新表設(shè)計(jì)方式新的設(shè)計(jì),我把整個(gè)表拆分成了兩個(gè)表,一個(gè)表存儲(chǔ)關(guān)系鏈,一個(gè)表用來(lái)做追溯標(biāo)記和查詢,大致如下:
關(guān)系表
admin_id #商戶ID product_id #商品ID code_max # 大碼 code_middle #中碼 code_min #小碼
追溯碼標(biāo)記表
admin_id #商戶ID product_id #商品ID code #追溯碼,不管大碼中碼還是小碼都會(huì)建一條數(shù)據(jù)存放在此字段 is_use # 是否使用 is_sell_out #是否出售 create_time #創(chuàng)建時(shí)間 update_time # 更新時(shí)間 is_delete #是否已刪除新的邏輯說(shuō)明
首先,在關(guān)系表里存儲(chǔ)的是關(guān)系,大碼、中碼、小碼都完整的村粗,可以通過(guò)大碼ID查詢到下面的所有中碼、小碼;
追溯碼標(biāo)記表,這個(gè)表專門(mén)管查詢和標(biāo)記追溯碼狀態(tài)等。
新的設(shè)計(jì)方式,會(huì)增加數(shù)據(jù)表數(shù)據(jù)的管理成本,也會(huì)增加數(shù)據(jù)量大小。
新的數(shù)據(jù)表關(guān)系數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)類似于這樣子:
大碼 | 中碼 | 小碼 |
---|---|---|
1 | 11 | 111 |
1 | 11 | 112 |
1 | 12 | 123 |
1 | 12 | 124 |
2 | 21 | 211 |
2 | 21 | 212 |
2 | 22 | 221 |
2 | 22 | 222 |
這個(gè)表結(jié)構(gòu)的說(shuō)明是避免對(duì)于關(guān)系鏈的數(shù)據(jù)邏輯不理解做的一個(gè)示例。
整個(gè)表經(jīng)過(guò)這樣的重新設(shè)計(jì)和梳理了之后,每次同時(shí)插入兩個(gè)表,并且可以用MySQL的批量插入操作進(jìn)行插入,插入速度具有非常大的提升。
數(shù)據(jù)重復(fù)對(duì)比在這套產(chǎn)品設(shè)計(jì)之中,整套的追溯碼是不能重復(fù)的,經(jīng)過(guò)了多方面思考,最后采用了in查詢機(jī)制,整套思路大致如下:
每次遍歷要導(dǎo)入的數(shù)據(jù)中的100條,然后用mysql的in去查詢,如果取到數(shù)據(jù),則遍歷數(shù)據(jù)標(biāo)記哪一條重復(fù)。不斷的循環(huán)遍歷去取,然后標(biāo)記輸出到CSV中,遍歷結(jié)束后,把標(biāo)記重復(fù)的文檔返回給用戶,讓用戶修改好后再進(jìn)行上傳。
不過(guò)關(guān)于這個(gè)數(shù)據(jù)對(duì)比的,我沒(méi)有更好的思路了,測(cè)試了18W條導(dǎo)入數(shù)據(jù)和數(shù)據(jù)表中的25W條數(shù)據(jù)對(duì)比,花的時(shí)間大約為13秒左右,就我的預(yù)估對(duì)比次數(shù)應(yīng)該為18W*25W,如果誰(shuí)在這方面有更好的數(shù)據(jù)對(duì)比算法,請(qǐng)留言告訴我,不勝感激。
僅以此文紀(jì)念自己踩過(guò)的坑,也同樣希望后人看到這篇文章后能得到一些解決思路。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/22845.html
閱讀 3112·2023-04-25 20:22
閱讀 3408·2019-08-30 11:14
閱讀 2654·2019-08-29 13:03
閱讀 3253·2019-08-26 13:47
閱讀 3296·2019-08-26 10:22
閱讀 1329·2019-08-23 18:26
閱讀 681·2019-08-23 17:16
閱讀 1969·2019-08-23 17:01