確定是數據庫性能瓶頸的出現,才須要分庫分表,可是隻要出現性能瓶頸問題就必定要分庫分表嗎?不必定
html
針對上述問題,咱們應該如何思考?前端
主要是解決單個數據庫存儲和訪問的壓力。分庫以後,單個數據庫存儲的數據量就少了,並且響應的請求也減小了。
redis
通常有性能問題均可以採用分庫分表解決,可是分庫分表並非性能問題的最優解。
例如沒法獲取鏈接問題,是由於單個數據庫最大鏈接數有限,若是分庫則可擴大鏈接數。
例如操做數據慢,分庫以後操做也相應的分到了多個數據庫商,操做確定會加快。
例如磁盤不足,分庫以後不一樣的庫在不一樣的物理機器商,磁盤容量確定比單個數據庫大。
算法
因爲數據存儲在不一樣的節點上,確定會致使數據不一致。分佈式不一致問題的研究可參考文章分佈式一致性那些事兒sql
當A庫的a表須要與B庫的b表關聯查詢怎麼辦?有以下幾種解決方案:
數據庫
當出現了跨接待你關聯的問題,必定要想想業務邏輯是否合理,若是真的要跨節點關聯,通常是經過rpc調用另一個節點的數據,組裝好再返回給前端或者第三方,對外無感知。緩存
跨節點多庫進行查詢時,會出現 limit 分頁,order by 排序的問題。好比有兩個節點,節點 1 存的是奇數 id=1,3,5,7,9……;節點 2 存的是偶數 id=2,4,6,8,10……執行 select*from user_info order by id limit 0,10
,則須要在兩個節點上各取出 10 條,而後合併數據,從新排序。
markdown
max、min、sum、count 之類的函數在進行計算的時候,也須要先在每一個分片上執行相應的函數,而後將各個分片的結果集進行彙總和再次計算,最終將結果返回。
併發
或者根據名稱模糊分頁查詢,而名稱字段單獨存放在i18n表,這個時候就須要先從i18n表中查出全部符合模糊查詢的記錄,而後從主表中分頁查詢,當i18n表很是大的時候很耗性能。
負載均衡
MySQL 的數據庫裏面字段有一個自增的屬性,Oracle 也有 Sequence 序列。若是是一個數據庫,那麼能夠保證 ID 是不重複的,可是水平分表之後,每一個表都按照本身的規律自增,確定會出現 ID 重複的問題,這個時候咱們就不能用本地自增的方式了。
解決方案:
有的分庫分表策略在數據庫擴容的時候不方便。好比按id的奇偶分表,當某一天按奇偶分表仍是太大,須要換再加一張表,則須要換一種分表策略,好比模3或者模5,則須要把以前的兩張表數據讀取出來從新分表;
有的表按月份分表,每月增長一張表,則不須要遷移歷史數據。
若是採用數值範圍分片,只須要添加節點就能夠進行擴容了,不須要對分片數據遷移。若是採用的是數值取模分片,則考慮後期的擴容問題就相對比較麻煩。
【1】MySQL分庫分表會帶來哪些棘手的問題?
【2】分庫分表須要考慮的問題及方案
【3】爲何須要分庫分表
【4】分佈式一致性那些事兒