菜哥,領導讓我開發新系統了mysql
這麼說領導對你仍是挺信任的呀~程序員
必須的,爲了設計好這個新系統,數據庫設計我花了好多心思呢web
作一個系統我以爲不該該從數據庫入手,應該從設計業務模型開始,先不說這個,說說你的數據庫設計的優點sql
爲了高性能我首先設計了分庫 分表策略,爲之後打下基礎數據庫
那你的數據量未來會很大嗎?分庫分表其實涉及到不少難題,你瞭解過嗎?編程
我以爲分庫分表很容易呀緩存
是嗎?服務器
說到數據庫分庫分表,不能一味的追求,咱們要明白爲何要進行分庫分表纔是最終目的。如今網上一些人鼓吹分庫分表如何應對了多大數據,殊不知針對不少人的業務來講,分庫分表策略也許並不是是銀彈,而是使人焦慮的焦油坑。微信
分庫分表是業務發展到必定階段,數據積累到必定量級而衍生出來的解決方案。當DB的數據量級到達一個階段,寫入和讀取的速度會出現瓶頸,即便是有索引,索引也會變的很大,並且數據庫的物理文件大的會使備份和恢復等操做變的很困難。這個時候因爲DB的瓶頸已經嚴重危害到了業務,最有效的解決方案莫過於DB的分庫分表了。架構
有的leader甚至架構師會在業務初期以本身的主觀意願就進行分庫分表,會爲之後業務高速發展作鋪墊。可是這裏我要表達我幾個觀點:
1. 若是當前這個業務並不是公司的核心業務,並且在業務是否能存活的前提下,初級的設計不要這麼複雜。若是每一個業務咱們都按淘寶那樣的規模作系統架構設計,未來不但會害死業務,更會讓程序員死的更慘,背上黑鍋的數量會更多。
2. 單臺數據庫的能力並不是想象中那麼脆弱。就算是mysql單表數據量大部分場景下也在百萬級別(固然這和存儲的具體數據格式有關),sqlserver更是不在話下,我司用的sqlserver,單表千萬級別數據的大有所在,億級的也有幾個,Oracle更是不用多說。
3. 若是業務週期比較短,或者人力物力不足的狀況下,盲目的在初期就進行分庫分表設計,更是給本身下了績效背D的套,
4. 系統的設計初期和公司的基礎數據有直接關係,好比微信這樣的數據規模,稍微一個小系統就有多是千萬甚至上億的數據級別,可是多數初創公司有多少能有這樣的級別呢?我這裏噴一句:有的創業公司號稱從XX大公司重金挖來的CTO,技術總監等等高人,尤爲是這些帶着金色光環的人在創業初期給開發人員埋雷,一個創業公司搞一套XX分佈式,XX設計,卻不知,在當前的公司環境下這些其實沒有必要,給公司帶來的更可能是苦不堪言。
一個好的系統設計者會在開始設計之初,充分考慮到各方面的綜合因素來綜合考慮。
根據業務劃分
說到分庫,菜菜這裏想多囉嗦一句:推薦你們根據業務來進行劃分,我一直在過去的文章中強調,一個系統的好壞,業務的邊界劃分起到舉足輕重的做用。業務按照規則劃分好邊界,每一個業務對應的數據庫天然而然就誕生了,不要站在數據庫的層面上去給業務分庫。有的leader會有這樣的行爲:某個表的數據量太大,分配到單獨的一個庫,結果致使的結果就是不少SQL語句必須跨庫Join。
具體的業務怎麼劃分呢?這個規則我不敢說,每一個公司的業務形態不一樣,劃分的維度就會不一樣。舉一個簡單的例子:一個典型的電商系統根據業務可劃分爲商品,訂單,這也是許多公司的典型業務劃分,可是我司根據本身的業務規則,劃分爲商品,訂單,支付。由於支付系統在我司是一個獨立的業務,不但包含了訂單的支付,還包含了不少其餘的支付場景。根據業務上的劃分,DB的層面就出現了商品DB,訂單DB和支付DB。
同一業務橫向劃分
除了根據業務垂直切分的策略以外,還有另一種經常使用的分庫方案,若是某個具體業務數據量比較大,能夠把這業務的數據庫根據某種規則來進行橫向切分。好比用戶信息的業務,當用戶量達到必定量級,有些公司會把用戶信息拆分到多個數據庫,說到這裏,有的同窗會問,這和拆分到多個表有什麼區別呢?若是把用戶信息橫切到同一個數據庫的多個表,若是這些表位於一個物理磁盤上,對於提升這個業務的寫入和讀取IO最大值並無什麼用處,可是若是分配到多個服務器上,意味着這個業務總體的最大IO獲得了提高,在必定程度上要比拆表效果要好,固然若是用到了表分區,每一個分區散落在不一樣的物理磁盤上,也不必定比分庫方式差。
把某個業務的DB按照規則橫向切分以後,固然也會引入新的問題,下邊會介紹。切分的規則在不少狀況下用的最多的就是哈希取餘的方式了,有時間我們在討論。
分庫引入複雜性
我在上文提到過,分庫分表並不是是銀彈,任何一種解決方案能解決一個問題,可是有可能會引入其餘問題,世界是公平的,計算機世界亦如此。那分庫會引入哪些問題呢?
1. 在執行了分庫以後,難以免會將本來邏輯關聯性很強的數據劃分到不一樣的表、不一樣的庫上,這時,表的關聯操做將受到限制,咱們多數狀況下沒法join位於不一樣分庫的表(由於多數公司都明令禁止跨庫sql),結果本來一次查詢可以完成的業務,可能須要屢次查詢才能完成。
2. 原來在單體DB環境下,能夠用DB的事務來保證一些操做的原子操做,可是在分散到多個數據庫的狀況下,統一管理這些操做變的困難。雖然一些大廠提供的也有跨庫的事務解決方案,可是性能上實在是差強人意,因此在不少狀況下並不實用。好比上邊提到的商品庫存支付,在單體應用的狀況下,三個業務在同一個數據庫,當發生支付業務,更改商品庫存和更新訂單狀態這兩個操做能夠利用數據庫提供的事物來完成,並且性能在可接受範圍以內,若是這三個業務分佈在不一樣的數據庫,有概率會發生只執行其中一個操做的狀況發生,其實這也是分佈式事物要解決的問題。在不少狀況下,分佈式事物是沒法避免的,根據業務綜合狀況適當採用分佈式事物也是一種有效的解決方案,最壞的狀況下,可能須要人工介入了。
3. 分庫對於DBA來講意味着工做量的成倍增長,原來只須要管理一個DB,如今卻要管理N個DB,並且每一個DB都須要備份,監控,甚至作高可用,擴展等工做。原來可能只須要一個DBA管理人員,分庫以後可能會須要兩個甚至三個,致使了公司在人力投入上的加大。
完