當我們系統達到瓶頸時候,最影響系統性能的永遠是最底層的。例如數據庫,所以數據庫優化相對重要,當數據庫性能由於數據量過大導致達到瓶頸的時候,我們會選擇對數據庫拆分或者對錶拆分,也就是分表分庫。分表分庫也分爲2種拆分方式:水平拆分、垂直拆分
1.水平分表 就是把一個表拆分成多個字段相同的表,把數據分開保存到不同的表上。
例如一個user表有一億用戶,如果只用一張表儲存查詢的時候會很慢
但是如果分成10個表來儲存這些用戶,則每個表只需要保存1000W數據,這樣效率就會大大提高
那如果分成10個表就需要制定相應的儲存規則,例如通過 user 表的 userName字段進行hash取模來存放哪個表
2.垂直分表 如果一個表的字段過多及儲存的空間較大則可以進行垂直拆分,就是把一個表的字段拆分開保存。
例如把user再拆分一個user_detail表,各個表保存不同的字段,然後使用ID關聯,避免字段過多導致查詢慢
3.水平分庫 如果一個數據庫實例承受不了目前的壓力,則可以使用多個數據庫實例,數據庫直接存在相同的表。
因爲數據庫表都是相同的,與水平分表類似,通過規則把數據保存到不同的數據庫
4.垂直分庫 現在程序都是分佈式或者模塊化,一個服務器可能只負責某部分業務,數據庫也可以使用類似的操作。
把不同業務的表分開儲存到不同的數據庫上
例如一個電商項目,把訂單類的表與商品類的表分開到不同的數據庫儲存
分表分庫之後帶來的問題:
1.數據唯一性:即使同庫分表或是分庫分表都需要解決的一個問題就是ID唯一,保證多個表之間的數據ID是唯一的。
可以自定義主鍵生成器,主鍵生成規則最好符合數據庫引擎的一些特性,比較可取的就是通過 時間+機器號+隨機數,時間放到最前面是保證數值在遞增
2.橫向擴展:上面舉例使用的是通過取模方式定位數據儲存的庫表,如果最開始取模是按10個表取,當我需要再加2個表則變成按12個表取模,這樣新數據不會有問題,但是查詢舊數據就存在問題。
當數據庫需要進行拆分的時候,或多或少都需要對數據做一定遷移,把舊數據重新分配到不同表中
3.部分表無法通過join關聯:例如把訂單表與商品表拆開儲存到不同的數據庫,如果需要根據訂單查詢商品信息,則難以通過join關聯查詢。
如果可以冗餘某些字段避免過多查詢
可以使用FEDERATED引擎遠程關聯
4.數據庫事務:還是使用訂單表與商品表拆開儲存到不同的數據庫的例子,一個下單操作需要在訂單類表添加訂單信息,同時需要在商品類表扣除庫存之類的,這之間的操作如何保證原子性。
可以使用某些分佈式事務的中間件解決
5.維護成本更高:當單庫單表變成多庫多表,其中的關係更復雜,維護成本更高
分表分庫的優點:
分表分庫的目的永遠只有一個: 因爲數據庫數據量過大導致效率低下,通過把數據拆分提高數據訪問性能