首頁  >  文章  >  資料庫  >  mysql中什麼時候分錶

mysql中什麼時候分錶

青灯夜游
青灯夜游原創
2022-06-27 15:52:532527瀏覽

mysql中適合分錶的情況:1、資料量過大,正常運維影響業務存取時,例如對資料庫進行備份需要大量的磁碟IO和網路IO、對一個表進行DDL修改會鎖住全表、對大表進行存取與更新出現鎖等待;2、隨著業務發展,需要對某些字段垂直拆分;3、單表中的資料量快速增長,當性能接近瓶頸時,就需要考慮水平切分。

mysql中什麼時候分錶

本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。

並不是所有表格都需要切分,主要還是看資料的成長速度。切分後會在某種程度上提升業務的複雜度,資料庫除了承載資料的儲存和查詢外,協助業務更好的實現需求也是其重要工作之一。

不到萬不得已不用輕易使用分庫分錶這個大招,避免"過度設計"和"過早優化"。在分庫分錶之前,不要為分而分,先盡力去做力所能及的事情,例如:升級硬體、升級網路、讀寫分離、索引優化等等。當資料量達到單表的瓶頸時候,再考慮分庫分錶。

那麼mysql中什麼時候考慮分錶

#1、資料量過大,正常運維會影響業務存取

這裡說的運維,指:

  • 對資料庫備份,如果單表太大,備份時需要大量的磁碟IO和網路IO。例如1T的數據,網路傳輸佔50MB時候,需要20000秒才能傳輸完畢,整個過程的風險都是比較高的

  • 對一個很大的表進行DDL修改時, MySQL會鎖住全表,這個時間會很長,這段時間業務不能存取此表,影響很大。如果使用pt-online-schema-change,使用過程中會建立觸發器和影子表,也需要很長的時間。在此操作過程中,都算為風險時間。將資料表拆分,總量減少,有助於降低這個風險。

  • 大表會經常存取與更新,就更有可能出現鎖定等待。將資料切分,以空間換時間,變相降低存取壓力

#2、隨著業務發展,需要對某些欄位垂直拆分

#舉個例子,假如專案一開始設計的使用者表如下:

mysql中什麼時候分錶

#在專案初始階段,這種設計是滿足簡單的業務需求的,也方便快速迭代開發。而當業務快速發展時,用戶量從10w激增到10億,用戶非常的活躍,每次登錄會更新 last_login_name 字段,使得 user 表被不斷update,壓力很大。而其他欄位:id, name, personal_info 是不變的或很少更新的,此時在業務角度,就要將 last_login_time 拆分出去,新建一個 user_time 表。

personal_info 屬性是更新和查詢頻率較低的,並且text欄位佔據了太多的空間。這時候,就要對此垂直拆分出 user_ext 表了。

3、資料量快速成長

#隨著業務的快速發展,單表中的資料量會持續成長,當效能接近瓶頸時,就需要考慮水平切分,做分庫分錶了。此時一定要選擇適當的切分規則,事先預估好資料容量

業務案例分析

1、用戶中心業務場景

使用者中心是一個非常常見的業務,主要提供使用者註冊、登入、查詢/修改等功能,其核心表為:

mysql中什麼時候分錶

任何脫離業務的架構設計都是耍流氓,在進行分庫分錶前,需要對業務場景需求進行梳理:

  • 用戶側:前台訪問,訪問量較大,需要保證高可用和高一致性。主要有兩類需求:

    • 使用者登入:透過login_name/phone/email查詢使用者訊息,1%請求屬於這種類型

    • 使用者資訊查詢:登入之後,透過uid來查詢使用者訊息,99%請求屬這種類型

  • 營運面:後台訪問,支援營運需求,依照年齡、性別、登陸時間、註冊時間等進行分頁的查詢。是內部系統,訪問量較低,對可用性、一致性的要求不高。

2、水平切分方法

當資料量越來越大時,需要對資料庫進行水平切分,上文描述的切分方法有"根據數值範圍"和"根據數值取模"。

"根據數值範圍":以主鍵uid為劃分依據,並依uid的範圍將資料等級切分到多個資料庫上。例如:user-db1儲存uid範圍為0~1000w的數據,user-db2儲存uid範圍為1000w~2000wuid數據。

  • 優點是:擴容簡單,如果容量不夠,只要增加新db即可。

  • 不足是:請求量不均勻,一般新註冊的用戶活躍度會比較高,所以新的user-db2會比user-db1負載高,導致伺服器使用率不平衡

"根據數值取模":也是以主鍵uid為分割依據,以uid取模的值將資料水平切分到多個資料庫上。例如:user-db1儲存uid取模得1的數據,user-db2儲存uid取模得0的uid資料。

  • 優點是:資料量和請求量分佈均均勻

  • #不足是:擴容麻煩,當容量不夠時,新增加db,需要rehash。需要考慮對資料進行平滑的遷移。

非uid的查詢方法

#水平切分後,對於按uid查詢的需求能很好的滿足,可以直接路由到具體資料庫。而按非uid的查詢,例如login_name,就不知道具體該訪問哪個庫了,此時需要遍歷所有庫,性能會降低很多。

對於用戶側,可以採用"建立非uid屬性到uid的映射關係"的方案;對於運營側,可以採用"前台與後台分離"的方案。

1、建立非uid屬性到uid的映射關係

  • 對應關係

##例如:login_name不能直接定位到資料庫,可以建立login_name→uid的映射關係,用索引表或快取來儲存。當存取login_name時,先透過映射表查詢出login_name對應的uid,再透過uid定位到具體的函式庫。

映射表只有兩列,可以承載很多數據,當數據量過大時,也可以對映射表再做水平切分。這類kv格式的索引結構,可以很好的使用cache來最佳化查詢效能,而且映射關係不會頻繁變更,快取命中率會很高。

  • 基因法

分庫基因:假如透過uid分庫,分成8個函式庫,以uid%8的方式進行路由,此時是由uid的最後3bit來決定這行User資料具體落到哪個庫上,那麼這3bit可以看為分庫基因。

2、前台與後台分離

對於使用者側,主要需求是以單行查詢為主,需要建立login_name/phone/email到uid的對應關係,可以解決這些欄位的查詢問題。

而對於營運側,很多批次分頁且條件多樣的查詢,這類查詢計算量大,回傳資料量大,對資料庫的效能消耗較高。此時,如果和用戶側公用同一批服務或資料庫,可能因為後台的少量請求,佔用大量資料庫資源,而導致用戶側存取效能降低或逾時。

這類業務最好採用"前台與後台分離"的方案,運營側後台業務抽取獨立的service和db,解決和前台業務系統的耦合。由於營運側對可用性、一致性的要求不高,可以不存取即時庫,而是透過binlog異步同步資料到營運庫進行存取。在資料量大的情況下,也可以使用ES搜尋引擎或Hive來滿足後台複雜的查詢方式。

【相關推薦:

mysql影片教學#

以上是mysql中什麼時候分錶的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn