一、爲什麼要分表分庫
數據庫數據會隨着業務的發展而不斷增多,因此數據操作,如增刪改查的開銷也會越來越大。再加上物理服務器的資源有限(CPU、磁盤、內存、IO 等)。最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。
數據庫存在IO和CPU瓶頸:
- IO瓶頸:
第一種: 磁盤讀的IO,數據庫緩存放不下,每次查詢是產生大量IO,降低查詢速度。
第二種:網絡IO,請求數據太多,帶寬不夠。
- CPU瓶頸:
第一種:sql語句,SQL語句中包含函數(join,group by,count…),非索引字段條件查詢等等,增加CPU運算操作。
第二種: 單表數據量太大,查詢是掃描的數據太多,SQL執行效率低下,CPU瓶頸就出現了。
二、如何分庫
1、水平分庫
- 以“字段”爲依據,按照一定策略(hash、rang、time),將一個庫中的數據拆分到多個庫中。
- 每個數據庫的結構都一樣。
- 所有數據庫中的數據並集就是全量數據。
場景: 提高數據查詢性能,把一個庫承擔負載分擔給了多個庫。
2、垂直分庫
- 以表爲拆分依據,按照業務規則不同,將不同表拆分到不同庫中。
- 每一個庫的結構是完全不一樣。
- 每個庫中的數據也不一樣,沒有交集。
- 所有庫的數據的並集就是全量數據。
三、如何分表
1、水平分表
- 以“字段”爲依據,按照一定策略(hash、rang、time),將表中的數據拆分到多個表中。
- 每個表的結構完全一樣。
- 每個表中的數據完全不一樣,並且沒有交集。
- 所有表並集就是全量數據。
2、垂直分表
- 以“字段”爲依據,表中字段過多時,按照規則,將表中的字段拆分到不同的表(主表/從表)。
- 每個表的結構是不一樣的。
- 每個表中的數據也不一樣的,每個表的字段至少有一個交集,一般是主鍵,關聯數據。
- 所有表的並集就是全量數據。
場景: 表的記錄不多,但是字段多,並且熱點數據和非熱點數據在一起,一行記錄存儲需要空間比較大。
四、拆分原則
1、能不拆分儘量不拆分,如果要拆分一定選擇合適的拆分規則。
2、數據拆分儘量通過數據冗餘或表分組來降低跨庫join的可能。
3、跨庫join是共同難題,所以業務讀取儘量少使用多表join。
五、分庫分表的好處
1、水平拆分優點
- 單庫單表的數據保存在一定量級,有助於提升性能。
- 切分表的結構相同,應用層改造較少,只需要增加路由規則就OK。
- 提供了系統穩定性和負載能力。(併發性能提高)
2、垂直拆分優點
- 拆分後業務明確。
- 系統進行整合和擴展就比較容易。
- 易於實現動靜分離,冷熱分離的數據庫表的數據模式。
五、分庫分錶帶來的問題
1、垂直拆分帶來的問題
- 部分業務表無法join,只能通過接口方式,提高了系統的複雜度
- 存在單表性能瓶頸,不易擴展。
- 事務處理複雜
2、水平拆分帶來的問題
- 拆分規則難以抽象
- 分片事務一致性難以解決
- 維護難度極大
- 跨庫join性能差
3、共同問題
- 分片規則和策略
- 分佈式全局唯一ID
- 多數據源管理問題
- 跨庫跨表join問題
- 跨節點合併排序分頁問題
- 事務複雜
- 數據管理難度加大