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