概述
數據庫子數據庫和子表的用處:數據庫的數據量不一定可控。沒有子數據庫和子表,隨著時間和業務的發展,數據庫中的表會越來越多,表中的數據量會越來越大,相應的數據操作、增刪改也會越來越大;另外,由于無法分布式部署,一臺服務器的資源(CPU、IO、磁盤、內存)是有限的,最后數據庫所能承載的數據量和數據處理能力都會遇到瓶頸。基于以上原因,我們需要使用數據庫子數據庫和子表操作。
一、基本思想
數據庫子表的目的是將一個數據庫分成多個部分,放在不同的數據庫上,以緩解單個數據庫的性能問題。
比如,當你面對一個海量數據的數據庫時,如果由于表的數量多而導致數據量大,建議采用垂直分段,即把緊密相關的表(比如某個應用模塊的表)放在一個數據庫(服務器)中。如果表格不多,但是每個表格中的數據很多,就需要使用水平分段。即按照一定的規則將表拆分到多個數據庫(服務器)中(常見的方法是按ID哈希)。當然,這只是一個例子,因為現實要比這復雜得多,需要結合兩種拆分方式才能讓系統性能更好(因為一個表的數據量可能非常大,超出了一個服務器的容量,所以需要在垂直拆分的基礎上進行水平拆分)。下面詳細描述垂直分段和水平分段。
二、數據庫的垂直切分和水平切分
垂直細分:分為功能模塊,如訂單庫、商品庫、用戶庫等。垂直細分最大的特點就是簡單,容易實現。
水平分段:同一個表的數據被分區保存到不同的數據庫。
三、案例分析
案例:簡單的購物系統,涉及以下表格
1.產品表(數據量10w,穩定)
2.訂單(數據量為200W,且有增加趨勢)
3.用戶表(數據量100w,有增加趨勢)
以mysql為例來描述水平拆分和垂直拆分。mysql數據庫可以容忍的數據從幾百萬靜態數據到幾千萬都有。
垂直拆分:
解決問題:表之間的io競爭。
未解決的問題:但是表中數據增長的壓力。
方案:將產品表和用戶表放在一臺服務器上,訂單表分別放在一臺服務器上。
水平拆分:
解決問題:單個表中數據增長的壓力。
未解決的問題:表之間的io競爭
方案:用戶表按性別分為男性用戶表和女性用戶表;訂單表通過已完成和已完成分為已完成訂單和未完成訂單;產品表未完成的訂單放在一臺服務器上,完成的訂單表和男性用戶表放在一臺服務器上,女性用戶表放在一臺服務器上(女性愛購物,數據增量大)。
四、拆分策略
如上所述,拆分的一般順序是先垂直拆分,再水平拆分。
垂直拆分的結果正好為水平拆分做了鋪墊。垂直拆分的思路是分析表與表之間的聚合關系,把緊密相關的表放在一個服務器上(大多數情況下可能是同一個模塊,也可能是同一個“聚合”,指的是域驅動設計中的“聚合根”)。這個“聚合根”也是水平拆分的基礎,所有與聚合根相關的數據都會被水平拆分成它們的shard片段。這樣跨分片關聯的可能性很小,應用也不必中斷已有的表間關聯。
五、拆分所帶來的問題
1.交易問題
解決問題的一般方法有兩種:分布式事務和通過應用程序和數據庫的聯合控制來實現事務。
方案一;使用分布式事務
優點:交友數據庫管理簡單有效。
缺點:性能成本高,尤其是碎片越來越多的時候
選項2:由應用程序和數據庫控制。
原理:將一個跨多個數據庫的分布式事務分成多個只在單個數據庫上的小事務,通過應用程序控制每個小事務。
優點:性能上有優勢。
缺點:應用程序在事務控制上需要靈活設計。
2.跨節點連接問題
避免join操作,將操作分成多個步驟。在第一次查詢的結果集中找出關聯數據的id,根據這些id發起第二次請求獲取關聯數據。
3.跨節點計數、排序依據、分組依據和聚合函數。
解決方案:類似于解決跨節點連接的問題,在每個節點上獲得結果,然后在應用程序端進行合并。
六、總結
數據庫劃分的原因是為了避免數據庫表之間的eio競爭,數據庫劃分的原因是為了避免單個表的數據量增加帶來的壓力。在實際項目中,首先要整理出整個數據秀逗魔導士的er圖,然后進行拆分。此外,我們需要適當地拆分和優化一些sql語句。
篇幅有限,這里介紹一下數據庫子數據庫和子表。后面會有更多DBA內容分享,感興趣的朋友可以關注一下。