雲開發資料庫重構:如何將欄位抽離成單獨的集合

2020-12-14 騰訊雲開發TCB

關於作者

Eric KK

曾供職於雲盾、簡書,資深前端工程師,we-plugin開源項目組成員,現任潮辦科技CTO,基於騰訊雲開發轉型全棧開發者,獨立完成多個微信小程序從0到1全功能完整上線運行。

「使用雲開發之後,一個小程序可以快速的從無到有上線運行,這個速度是傳統開發不能比的,特別適合初創團隊快速上線產品搶佔市場或試錯。而使用雲開發,我們通常要做的第一件事就是設計資料庫,雲開發的資料庫使用結構化的文檔來存儲數據,不再是關係型資料庫裡每個行列交匯處都必須有且只有一個值,它可以是一個數組、一個對象,或者更加複雜的嵌套。

在初期產品需要快速出可用原型,上線時間緊迫的情況下,資料庫設計難免會有欠考慮的地方,等產品開始進入迭代器就可能會有重構需求。團隊最近對項目進行了重構,寫一篇文章分享我們在做重構的一些心得。」

目的

這次資料庫重構只有一個目的,把一個最初內嵌的欄位提取出來,單獨創建一個集合來管理。也就是把反範式化設計的資料庫結構轉成範式化的設計

關於範式化和反範式化,你可以看雲開發布道師東哥的文章:

https://club.cloudbase.net/handbook/tcb/1203.html

舊數據方案的痛點

在產品上線的第一個版本時,bagList欄位是內嵌在一個user文檔裡的,如下:

這裡的數據是精簡版,真實情況還會有很多商品信息、用戶信息等,此處只是舉例說明。

這樣的反範式化設計在最初上線的版本中並沒有什麼問題,因為商品價格較高,早期也認為用戶並不會大量購買。然而沒想到的是,在經過一波運營宣傳後,用戶量開始猛增,其中也出現了一些土豪用戶,他們的購買數量已經不是個位數了,有的都超過了100件以上,此時bagList欄位的數組長度就變得非常大。

在這個時候,數據分頁、商品發貨、修改商品信息就已經很難維護,一直使用了層層的聚合操作先查詢出來,然後再修改。猶豫不決之際,新的開發需求出現,要求可以讓用戶之前互換數據,原有的數據結構想要實現類似的功能存在較高的實現成本。因此,決定乾脆重構資料庫,提升開發效率。

重構步驟

bagList欄位單獨拿出來形成一個集合的好處有很多,數據分頁很方便,修改商品信息很簡單,且很多雲資料庫的原子操作修改都可以直接使用,更重要的是新需求互換功能只需要修改對應商品的所有者 userid 就可以完成。但此時內嵌結構已經使用了很久,數據也已經記錄了很多,如何把這些歷史數據無縫銜接的拿出來成了問題,這裡使用了一系列的聚合操作來完成。

這裡用的是雲開發管理控制臺自帶的高級操作腳本,首先第一步開啟聚合模式,在聚合中單次limit最大數現為10000,因改版時用戶數正好低於10000,所以這裡直接拉到最大。然後使用match來刪選user集合中bagList欄位不為空數組的文檔。緊接著使用project選定在下一階段想要的展示的欄位,_id欄位默認存在,其餘欄位直接捨棄。此時的執行結果如下圖:

接下來我們就需要用unwind來拆分bagList,拆分完的數據結構如下:

此時每一個商品已經單獨抽離出來,如果此時的結構已經達到了想要的要求,那就可以直接使用現有數據,如果還想自定義一下,那就可以繼續使用聚合操作來完成,如上面我因為還有其他需求,使用聚合再次改變了一些結構寫法,聚合的操作可以去雲開發文檔聚合學習。

不過,聚合出來的數據並不是嚴格的json數據,雖然現在的雲開發控制臺的高級腳本可以批量添加數據,add方法中的data可以為數組,這在數據量小的情況下可以直接使用,但我們這次聚合出來幾千條數據,經測試,雲開發的高級腳本並不支持那麼大的數據量一次性導入,那麼我們可以使用資料庫的json格式導入。

創建一個新集合products,這裡使用vscode把我們聚合出來的數據複製粘貼到一個名為products.json的新文件中(名稱隨意),然後將最外層的[]包裹刪除,全局搜索 },換行{ 替換為 }換行{ ,把每條數據之間的逗號去除(注意:在搜索的時候,換行也要,不然內嵌數據的逗號也會被替換),保存並使用 json方式把數據導入到products集合就大功告成啦。

總結

在開發的過程中,難免會遇到需要重構資料庫的場景,我自己沒有搜索到相關的文檔,便將自己的實踐經驗分享出來,做第一個吃螃蟹的人,供大家參考。

如果你對重構方面有任何問題和想法,歡迎留言和一起討論。

相關焦點

  • 如何在微信開發者工具中開啟雲開發
    ,沒有嘗試過雲開發;這兩天看了下小程序雲開發,發現其中有好多要學;首先,要開通雲開發服務;其次,要創建並部署雲函數;了解如何操作雲資料庫等。下面利用實例說明:操作如下:1、開通雲服務後,點擊微信開發者工具【雲開發】,打開雲開發控制臺
  • Java開發工程師如何在Mysql資料庫中創建表
    所以為了不影響以後的操作,建議在刪除表之後將FOREIGN_KEY_CHECKS=1重新啟用外鍵約束。,大家將這段複製到sqlPlus或者navicat中執行即可。在正式開發環境中,sql建表語句都不是我們手動寫出來的,有很多免費的資料庫建模工具如powerdesigner,幫助我們構建資料庫模型來自動生成sql語句。非常的方便,Mybatis也有一個非常好用的插件叫做逆向工程,它可以幫我們通過sql腳本而生成對應的java 實體類,是持久層開發人員的神器啊,以後都會講到。
  • 2分鐘上手、3小時學會無代碼軟體開發——庫表欄位
    項目運行時,項目配置文件設定的資料庫中庫表如果沒有如果沒有對應欄位,則會在啟動WEB服務時自動新建屬性定義欄位屬性主要包括:是否主鍵、是否非空、默認值 (建議在開發平臺只處理這幾個,其他欄位屬性設定用資料庫管理軟體設定,參考本章「資料庫獨立管理
  • 重構:改善既有代碼的設計
    如果只是代碼間相似,並非完全相同,那麼可以將相似部分和差異部分拆開,構成單獨的函數。然後你可以使用模板方法的設計模式。如果兩個毫不相關的類中出現重複代碼,則可以將重複代碼提煉成一個函數放到一個獨立類中或者只放在某一個類中(總之要放在合適的地方),然後其他類都去調用這個函數。
  • 從「如何設計用戶超過1億的應用」說起—資料庫調優實戰
    因此,更經濟、更方便擴展的雲服務平臺成為首選。在對比現有各家雲服務後,我們選擇了穩定性與成熟度都經過大量用戶檢驗的阿里雲。但要構建高性能的SaaS應用,僅憑雲服務基礎設施是不夠的。如何基於雲服務平臺設計並實施符合自身業務特點的系統架構,也是決定產品性能的關鍵。本文將講述我們如何利用雲服務,使用相對經濟的方案,解決海量用戶的資料庫使用問題。
  • EXCEL操作資料庫表,自動判斷欄位類型,批量添加數據到資料庫表
    使用SQL語句添加數據時,不同的欄位類型要求不一樣,字符類型要求要用單引號括起來,數字類型則什麼都不用加,時間日期類型要前面後井號"#",如果不按要求寫語句將會出錯。所在在添加數據時要把每個欄位類型都弄清楚,很容易出錯,所以研究了一下自動檢測欄位類型,然後根據不同的類型為每個欄位使用不同的寫法。
  • 最大的在線天然產物資料庫:Coconut資料庫
    具有相同性質的文檔被組織在集合中,這些集合等效於基於SQL的資料庫表。MongoDB特別適合大型和複雜數據,支持多種索引編制,包括文本索引編制,可在文本索引欄位中增強文本搜索,並包含多種內置搜索和分析功能。
  • 如何創建access資料庫
    如何創建access資料庫?若要創建Access資料庫,需要首先創建一個資料庫表,然後定義要存儲在該表中的所有欄位的名稱。使用Access資料庫表,您可以將文件劃分為單獨的部分。例如,一個資料庫表可以保存您所有客戶的姓名和地址,第二個資料庫表可以保存您所有員工的姓名和地址,而第三個資料庫表可以保存您的供應商的姓名和地址。 Access將所有這些相關信息存儲在硬碟上保存的單個Access文件中。若要設計Access資料庫,可以從頭開始創建資料庫,也可以使用可以修改的現有模板。設計資料庫意味著既要定義用於存儲信息的欄位數,又要定義每個欄位可以容納的最大數據量。
  • NET開發-如何通過SSMS工具或SQL語句給SQL Server資料庫添加數據
    .NET開發-SQL Server資料庫1.概述使用.NET開發的應用程式,一般都有前臺展示和後臺管理功能,對於後臺管理,主要用於對數據的管理通過後臺管理系統將數據添加到資料庫中存儲,其保存過程是,首先通過C#代碼,通過填寫的數據拼接成SQL語句,然後再通過ADO.NET對象,將帶有數據的SQL語句發送到SQL Server中,此時,在SQL Server資料庫中,就可以通過SQL語句將數據添加到資料庫的表中。
  • 技多不壓身 | 產品經理需知的那些資料庫基礎知識
    那麼,如何理解某一組列作為主鍵呢?當我們無法用單獨的某一列來代表一條記錄時,我們就要採用某兩列或者某幾列來共同代表一條記錄。SQL(Structured Query Language)是結構化查詢語言,可以用來和資料庫通信,絕大部分DBMS都支持SQL,簡單的說就是通過編寫SQL語句來操作資料庫。在下面的操作中,筆者也將以MySQL+Navicat作為基礎開發環境,以SQL語法為說明。
  • 360 私有雲平臺 MySQL 自動化實現剖析
    這個是 HULK 用戶端的首頁,而其中資料庫服務又集合了 MySQL、Redis、Mongodb、Greenplum、ElasticSearch 等,今天的主角是 MySQL,MySQL 作為基礎服務是 DBA 服務體系中的基石,在 HULK 雲平臺中,MySQL 實例數已經突破 9000+,日訪問量超過 200 億,單份數據量也已經超過了 270TB。
  • MySQL資料庫教程-數據表欄位約束
    MySQL資料庫教程-數據表欄位約束為保證資料庫中存儲數據的規範化,一般需要在定義欄位時進行欄位規範與約束的定義。保證在進行數據錄入時,資料庫能夠通過這個規則、約束、規範檢查所錄入的數據,防止錯誤及不符合要求數據的錄入。本文主要介紹數據表欄位約束類型及其基本語法,為下一步創建數據表提供基礎與依據。
  • sql替換資料庫欄位中的字符
    某些時候我們要修改資料庫欄位中的部分字符串,如果內容少時一個一個替換,內容多時,就不能一個一個的替換了,因為這樣不僅耗時還容易出錯。下面就用sql批量進行替換。替換shopping_hw表中欄位hw_pic,內容「*common」替換為「+play」.
  • [精品]資料庫設計60個技巧(必看)
    這裡有10 個技巧專門涉及系統生成的主鍵的正確用法,還有何時以及如何索引欄位以獲得最佳性能等。第4部分 — 保證數據完整性討論如何保持資料庫的清晰和健壯,如何把有害數據降低到最小程度。暢想未來,但不可忘了過去的教訓我發現詢問用戶如何看待未來需求變化非常有用。這樣做可以達到兩個目的:首先,你可以清楚地了解應用設計在哪個地方應該更具靈活性以及如何避免性能瓶頸;其次,你知道發生事先沒有確定的需求變更時用戶將和你一樣感到吃驚。— chrisdk一定要記住過去的經驗教訓!
  • 資料庫設計經驗談
    所以我歸納歷年來所走的彎路及體會,並在網上找了些對資料庫設計頗有造詣的專業人士給大家傳授一些設計資料庫的技巧和經驗。精選了其中的 60 個最佳技巧,並把這些技巧編寫成了本文,為了方便索引其內容劃分為 5 個部分:第 1 部分 - 設計資料庫之前這一部分羅列了 12 個基本技巧,包括命名規範和明確業務需求等。
  • 基於MySQL的高性能資料庫應用開發
    一、高性能資料庫的選擇---- 在資料庫的應用開發中,常常會遇到性能和代價的之間矛盾。開始,我們採用了MS SQLServer 6.5 作為資料庫系統,用Visual C++ 6.0開發了訪問資料庫的前端,應用ODBC數據接口,在進行了大量的資料庫配置和程序優化後,發現仍不能滿足性能要求。
  • MySQL資料庫表結構複製、數據插入和表欄位內容更新
    MySQL資料庫表結構複製、數據插入和表欄位內容更新在實際項目開發中,我們在操作MySQL資料庫表時,通常因為新需求需要修改表數據,為了不破壞數據完整性和一致性,我們可以通過SQL語句快速複製表結構及數據,然後對複製的表進行相關操作,驗證通過後,再對原表進行對應處理,這樣更安全可靠
  • 最全的資料庫分類及實例介紹
    下面本文將簡單介紹一下各種類型的數據。關係型資料庫: 這種類型的資料庫是最古老的資料庫類型,關係型資料庫模型是把複雜的數據結構歸結為簡單的二元關係(即二維表格形式), 如圖2是一個二維表的實例。通常該表第一行為欄位名稱,描述該欄位的作用,下面是具體的數據。在定義該表時需要指定欄位的名稱及類型。
  • 天貓面試真題:如何進行資料庫設計?
    在軟體開發的過程中,資料庫設計是非常重要的,它需要根據需求分析設抽象出 E-R 圖,邏輯結構設計,資料庫選型,物理設計,實施及運維。下面就聊聊那些年資料庫設計的那些事。數Attribute(前期可能由於需求不明確,可以只做確認的內容),Entity 通過 PowerDesigner 的正向工程轉換成資料庫裡的數據表,Attribute 就是表的欄位;數據表通過 ORM 映射到 Java 裡的就是 Class,欄位就是 private 屬性。
  • 五大主流資料庫模型
    導讀:無論是關係型資料庫還是非關係型資料庫,都是某種數據模型的實現。本文將為大家簡要介紹5種常見的數據模型,讓我們來追本溯源,窺探現在流行的資料庫解決方案背後的神秘世界。訪問資料庫中的數據取決於資料庫實現的數據模型。數據模型會影響客戶端通過API對數據的操作。不同的數據模型可能會提供或多或少的功能。一般而言,數據模型不會直接提供過多的功能,許多功能必須由客戶端自行實現。數據模型決定了客戶端如何對數據進行編碼存儲。