mysql中適合分錶的情況:1、資料量過大,正常運維影響業務存取時,例如對資料庫進行備份需要大量的磁碟IO和網路IO、對一個表進行DDL修改會鎖住全表、對大表進行存取與更新出現鎖等待;2、隨著業務發展,需要對某些字段垂直拆分;3、單表中的資料量快速增長,當性能接近瓶頸時,就需要考慮水平切分。
本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。
並不是所有表格都需要切分,主要還是看資料的成長速度。切分後會在某種程度上提升業務的複雜度,資料庫除了承載資料的儲存和查詢外,協助業務更好的實現需求也是其重要工作之一。
不到萬不得已不用輕易使用分庫分錶這個大招,避免"過度設計"和"過早優化"。在分庫分錶之前,不要為分而分,先盡力去做力所能及的事情,例如:升級硬體、升級網路、讀寫分離、索引優化等等。當資料量達到單表的瓶頸時候,再考慮分庫分錶。
那麼mysql中什麼時候考慮分錶
#1、資料量過大,正常運維會影響業務存取
這裡說的運維,指:
對資料庫備份,如果單表太大,備份時需要大量的磁碟IO和網路IO。例如1T的數據,網路傳輸佔50MB時候,需要20000秒才能傳輸完畢,整個過程的風險都是比較高的
對一個很大的表進行DDL修改時, MySQL會鎖住全表,這個時間會很長,這段時間業務不能存取此表,影響很大。如果使用pt-online-schema-change,使用過程中會建立觸發器和影子表,也需要很長的時間。在此操作過程中,都算為風險時間。將資料表拆分,總量減少,有助於降低這個風險。
大表會經常存取與更新,就更有可能出現鎖定等待。將資料切分,以空間換時間,變相降低存取壓力
#2、隨著業務發展,需要對某些欄位垂直拆分
#舉個例子,假如專案一開始設計的使用者表如下:
#在專案初始階段,這種設計是滿足簡單的業務需求的,也方便快速迭代開發。而當業務快速發展時,用戶量從10w激增到10億,用戶非常的活躍,每次登錄會更新 last_login_name 字段,使得 user 表被不斷update,壓力很大。而其他欄位:id, name, personal_info 是不變的或很少更新的,此時在業務角度,就要將 last_login_time 拆分出去,新建一個 user_time 表。
personal_info 屬性是更新和查詢頻率較低的,並且text欄位佔據了太多的空間。這時候,就要對此垂直拆分出 user_ext 表了。
3、資料量快速成長
#隨著業務的快速發展,單表中的資料量會持續成長,當效能接近瓶頸時,就需要考慮水平切分,做分庫分錶了。此時一定要選擇適當的切分規則,事先預估好資料容量
業務案例分析
1、用戶中心業務場景
使用者中心是一個非常常見的業務,主要提供使用者註冊、登入、查詢/修改等功能,其核心表為:
任何脫離業務的架構設計都是耍流氓,在進行分庫分錶前,需要對業務場景需求進行梳理:
用戶側:前台訪問,訪問量較大,需要保證高可用和高一致性。主要有兩類需求:
使用者登入:透過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的映射關係
對應關係
2、前台與後台分離
對於使用者側,主要需求是以單行查詢為主,需要建立login_name/phone/email到uid的對應關係,可以解決這些欄位的查詢問題。 而對於營運側,很多批次分頁且條件多樣的查詢,這類查詢計算量大,回傳資料量大,對資料庫的效能消耗較高。此時,如果和用戶側公用同一批服務或資料庫,可能因為後台的少量請求,佔用大量資料庫資源,而導致用戶側存取效能降低或逾時。 這類業務最好採用"前台與後台分離"的方案,運營側後台業務抽取獨立的service和db,解決和前台業務系統的耦合。由於營運側對可用性、一致性的要求不高,可以不存取即時庫,而是透過binlog異步同步資料到營運庫進行存取。在資料量大的情況下,也可以使用ES搜尋引擎或Hive來滿足後台複雜的查詢方式。 【相關推薦:mysql影片教學】#
以上是mysql中什麼時候分錶的詳細內容。更多資訊請關注PHP中文網其他相關文章!