mysql先分了10張表,後續在分表如何處理?

老許


MySQL分庫分表(其他關係型數據庫也相似),通常的方案都用主鍵mod分表的數量,來把數據路由到某一個數據庫分片上。例如分了10張表,那麼就是ID%10,得到結果0-9,代表不同的表。

但是當數據量進一步增多的時候,單庫的數據量達到了一定的級別之後,那麼就需要分更多的表,那麼這時候有哪些處理方案呢?

做數據遷移

最簡單暴力,也是最麻煩的一個方案。

因為當分表(分庫)數量增多的時候,因為分片規則的變化,每個表的數據都要被重新分配到多個新的表;這種方法雖然最直接,但是帶來的問題也非常大:

  • 數據遷移時間會比較長,需要遷移時間;

  • 如果業務不能停的話(在線遷移),還要解決增量數據和歷史數據一致性的問題;

不做數據遷移

那麼有沒有方法,當數據增長到現有分表極限的時候,加表或者加庫的時候,可以避免數據的遷移呢?說白了,我們需要增加分表算法的複雜性,讓算法可以兼容增加分表前後的數據路由:

  • 先說一個簡單的辦法,(為了方便講述,下面就把id當做分表字段),如果id是一個增長的全局序列,每個表存500萬的數據,那麼可以id=1-500萬存到table_1,id=500萬零1-1000萬存到table_2,理論上這種方法是可以無限擴容的,但是問題也顯而易見,就是每個階段的數據insert會集中在一個表/庫上,雖然能避免數據遷移的問題,但是數據熱點的問題沒有解決。

  • 如果id是一個增長的全局序列,當前有十張表,那麼分表的算法為:id%10,根據0-9路由到10個表中;當表擴到20張的時候,擴容那一刻取max_id,那麼未來分庫的算法也就變成了:
if(id
  • 有些分表的算法本身就帶時間戳,可以基於id中的時間戳來實現,比如Twitter-Snowflake算法,這個算法是一個64位的Long值,前42位就是一個精確到毫秒的時間戳,那麼我們的分庫算法也就可以以某個時間點來判斷:


if(id中的時間

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


會點代碼的大叔


分表一定要慎重,分表影響最大的就是查詢,對於order by或者group by類型的查詢很頭疼。對於題主的問題,我想只能有以下方法了。

腳本同步

只能先建好要分的表的,然後通過腳本,讀取老數據根據新的規則重新插入新的表,同時新數據也要確保同時進入新的表,腳本要在用戶訪問最少的時間段執行,降低負載。待數據遷移同步完成後,切換新的規則,切換也要在流量少的時候切換。

分庫

再建立個數據庫,同時建立相同的分表,表的分割規則一樣,只不過是另一個庫。然後新的數據進入新的表,根據時間節點來判斷,數據該走哪個庫

Es存儲

es來存儲海量查詢,並且支持豐富的查詢,es是個不錯的選擇

總結

不管是分庫還是分表,一定要結合業務來設計


修煉內功的程序員


歡迎關注我,一個程序員老司機,和你分享編程、運營、需求等等經驗和趣事。

根據你的問題描述,其實就是對MySQL數據表進行重新分表,下面我來和你分享一下我的觀點,希望能夠幫助到你。

首先你已經有了10個表,那麼現在分表肯定需要重新組織這10個表的數據,所以我們可以這樣做,首先創建好你的新分表,比如50個新的分表,然後用程序依次將這10個表的數據按照新規則插入到新的分表裡面,完成之後,將應用程序裡面的數據表名稱改成新數據表,從而完成整個操作。

但是這裡有一個問題,因為我們的數據隨時都在增加或者修改、刪除,如果在業務繁忙的時候來進行的話,很容易導致數據丟失或者數據不完整的情況,所以,儘可能將這個分表操作放在晚上或者業務不繁忙的時候,甚至關閉整個系統一段時間都可以,如果選擇晚上的話,怎麼處理好新增的數據和修改的數據呢?可以考慮臨時增加幾個數據表觸發器,然後在分表完成之後,根據這些觸發器來進行修改數據的修復。

不過在做項目的時候,我們還是儘可能將這個設計好,因為重新分表的成本非常高。


分享到:


相關文章: