1. 程式人生 > >資料庫分表和分庫 一點積累

資料庫分表和分庫 一點積累

資料庫分庫分表一般是儲存了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致資料庫在查詢和插入的時候耗時太長,效能低下,如果涉及聯合查詢的情況,效能會更加糟糕。分表和表分割槽的目的就是減少資料庫的負擔,提高資料庫的效率,通常點來講就是提高表的增刪改查效率。

什麼是分表?

分表是將一個大表按照一定的規則分解成多張具有獨立儲存空間的實體表,我們可以稱為子表,每個表都對應三個檔案,MYD資料檔案,.MYI索引檔案,.frm表結構檔案。這些子表可以分佈在同一塊磁碟上,也可以在不同的機器上。app讀寫的時候根據事先定義好的規則得到對應的子表名,然後去操作它。

什麼是分割槽?

分割槽和分表相似,都是按照規則分解表。不同在於分表將大表分解為若干個獨立的實體表,而分割槽是將資料分段劃分在多個位置存放,可以是同一塊磁碟也可以在不同的機器。分割槽後,表面上還是一張表,但資料雜湊到多個位置了。app讀寫的時候操作的還是大表名字,db自動去組織分割槽的資料。

MYISAM 分表方法,就是根據自增id的尾數來分,也就是說分0-9一共10個表,其取值也很好做,就是對10進行取模。另外,還可以根據某一欄位的md5值取其中幾位進行分表,這樣的話,可以分的表就很多了。

 

 如果把1.5千萬作為一個最大上限值, 也就是0.5倍的上浮空間, 這時我們把1.5倍的x=每張表的1千萬(1.5x=1千萬),那麼x=0.67千萬, y(y是分表數)張0.67千萬=一億, y=15,   這時在按2的倍數建立表的話,就是16了。 複雜的可能會涉及到自定義函式或雜湊演算法, 我現在拿分成十張表距離, 你可以按使用者id結尾0,1,2,3...9的不同存到10張表裡邊去。  如果把1.5千萬作為一個最大上限值, 也就是0.5倍的上浮空間, 這時我們把1.5倍的x=每張表的1千萬(1.5x=1千萬),那麼x=0.67千萬, y(y是分表數)張0.67千萬=一億, y=15,   這時在按2的倍數建立表的話,就是16了。

MySQL的單表承載的資料量有限,一般在1000萬以內,欄位多一些還會更少,我們解決這種業務就需要對資料進行拆分,也叫sharding ,將一個表拆分多個表,或者多個數據庫,分表邏輯分庫差不多。

拆分需要考慮的資料和業務邏輯。按照使用者維度、商品維度或訂單維度等拆分。

拆分因子選擇

因子選擇,要看這個表所支撐的業務。

舉例1、京東的京豆

京豆是屬於使用者維度的,我們的操作都是查詢某個人的京豆,所以這個京豆庫存流水資訊就可以按照使用者維度進行拆分,保證同一個人的京豆都儲存在同一張表裡面。

舉例2、電商的商品資訊

商品資訊屬於商家維度,我們一般都是進到一個店鋪,檢視這個店鋪有哪些商品,商家檢視自己的商品,所以這個商品資訊就可以按照商家維度拆分,保證同一個商家的資訊在同一表裡面。

極端例子:訂單表

訂單表即屬於商家,又屬於使用者,此時我們的選擇是優先使用者,可以按照使用者維度進行拆分,其次通過冗餘索引或冗餘資料來為商戶提供服務,比如建立一套商戶維度的資料,然後商戶維度資料採用非同步非實時的機制進行同步資料。

拆分方法

如果你的業務是按照時間進行分表,每隔一段時間建立一個新表的話,就沒有具體的拆分方式了,一定時間建立一個新表就可以了,但如果是有拆分因子,可以按照如下步驟考慮:

1、預估容量

預估該系統要支撐幾年,大概的一個數據量,按照每個表1000w左右進行評估,如果未來5年可以達到1億資料,那麼拆分10張表即可,加上一定的上浮空間,一般用2的倍數,拆分成16張就夠了。

2、考慮擴充套件性

如果我們16張表不夠用的時候,該怎麼辦,那32張是否足夠,如果提前做好擴充套件性。

實踐

比如每個訂單,都給使用者發放一定的獎勵金,我們要記錄每次發放的獎勵金資訊,我們按照使用者維度進行分表;

1、每天100w訂單,也就100w條記錄

2、系統支撐5年,5*365*100w 約等於 18.25億

3、每張表最多存1000w資料,大約182張表

考慮到擴充套件性 我們準備最多分256張表(2的倍數)可以先拆分出16張表,隨著業務擴充套件最多分256張。

 

考慮到擴充套件性 我們準備最多分256張表(2的倍數)可以先拆分出16張表,隨著業務擴充套件最多分256張.

表的命名,user_001,user_016,user_032 ... user_240 累計16張表,選擇等步長為了每個表之間可以做擴充套件

一致性Hash演算法