程序员修神之路--做好分库分表其实很难之二
菜菜哥,上次聽你給我講了分庫的情況后,我明白了很多,能再給我講講分表嗎
有收獲就好,分表其實有很多情況和分庫類似
還有不一樣的情況嗎?
有呀,本來數據庫和表是不同層面的東西,肯定有差異
那你給講講唄
講可以,一杯coffee如何?
為什么分
在正式開始之前,菜菜還是要強調一點,你的數據表是否應該分,需要綜合考慮很多因素,比如業務的數據量是否到達了必須要切分的數量級,是否可以有其他方案來解決當前問題?我不止一次的見過,有的leader在不考慮綜合情況下,盲目的進行表拆分業務,導致的情況就是大家不停的加班,連續幾周996,難道leader你不掉頭發嗎?還有的架構師在一個小小業務初期就進行表拆分,大家為了配合你也是馬不停蹄的加班趕進度,上線之后反而發現業務數據量很小,但是代碼上卻被分表策略牽制了太多。拆表引起的問題在特定的場景下,有時候代價真的很大。
數據庫表的拆分解決的問題主要是存儲和性能問題,mysql在單表數據量達到一定量級后,性能會急劇下降,相比較于sqlserver和Oracle這些收費DB來說,mysql在某些方面還是處于弱勢,但是表的拆分這個策略卻適用于幾乎所有的關系型數據庫。
數據庫進行表拆分不要太盲目
分表策略
表的拆分和數據庫的拆分有相似之處,但是拆分的規則也有不同。以下的拆分規則針對的是拆分一個表。
橫向切分
橫向切分是諸多業務中最常用的切分方式,本質是把一個表中的數據行按照規則分散到多個表中,比如最常見的按照ID范圍,按照業務主鍵的哈希值等。至于表數據到達什么數量級之后進行切分,這和表中存的數據格式有關,比如一個表只有幾列的int字段肯定要比幾列text類型的表存儲的極限要高。姑且認為這個極限是1000萬吧。但是作為一個系統的負責人或者架構師來說,當表的數據量級到達千萬級別要引起重視,因為這是一個系統性能瓶頸的隱患。
相對于數據表的橫向切分,在符合業務優化的場景下我更傾向于做表分區,按照規則把不同的分區分配到不同的物理磁盤,這樣的話,業務里的sql語句幾乎可以不用改動。我司的一個sqlserver數據庫,某個業務的表做了表分區之后,已經到達幾十億級別的數據量,但是查詢和插入速度還是能滿足業務的需求(優化一個系統還是要花精力優化業務層面)。
垂直切分
說到垂直拆分,表也可以按照業務來拆分,比如一個數據庫中有用戶的信息,根據業務可以劃分為基礎信息和擴展信息,如果對業務有利,完全可以拆分為基礎信息表和擴展信息表。當然也可以按照別的規則來拆,比如把訪問頻繁的信息拆分成一個表,其他不頻繁的信息拆分成一個表,具體的拆分規則還是要看當時要解決的問題是什么。垂直拆分可能會引入一定復雜性,比如原來查詢一個用戶的基礎信息和擴展信息可以一次性查詢出結果,分表之后需要進行Join操作或者查詢兩次才能查詢出結果。
分表代價
1. 數據表垂直切分之后,原來一次查詢有可能會變為連表的join查詢,在一定程度上會有性能損失。
2. 數據表橫向切分需要一定的規則,常用的主要有兩種規則:范圍切分和哈希值切分。范圍切分是指按照某個字段的范圍來切分,比如用戶表按照用戶ID來切分,id為1到10萬的位于User表1中,100001到200000萬的位于User2中,這樣切分的優勢是,可以無限的擴容下去,不用考慮數據遷移的問題,劣勢就是新表和舊表數據分布不均勻,而且分表的范圍選取有一定難度,范圍太小會導致表太多,太大會導致問題根本上沒有解決的困惑。另外一種分表策略就是把某一列按照哈希值來路由到不同的表中,同樣以用戶ID為例,假如我們一開始就規劃了10個數據庫表,路由算法可以簡單地用 user_id %10的值來表示數據所屬的數據庫表編號,ID為985的用戶放到編號為 5的子表中,ID為10086的用戶放到編號為 6 的字表中。這種切分規則的優勢是每個表的數據分布比較均勻,但是后期擴容會設計到部分數據的遷移工作。
3. 表拆分之后如果遇到有order by 的操作,數據庫就無能為力了,只能由業務代碼或者數據庫中間件來完成了。
4. 當有搜索的業務需求的時候,sql語句只能是Join多個表來進行連表查詢了,類似的還有統計的需求,例如count的統計操作。
●程序員過關斬將--你為什么還在用存儲過程?●程序員過關斬將--小小的分頁引發的加班血案●程序員修神之路--問世間異步為何物?●程序員修神之路--提高網站的吞吐量?●程序員修神之路--?分布式高并發下Actor模型如此優秀?●程序員過關斬將--論商品促銷代碼的優雅性●程序員過關斬將--你的面向接口編程一定對嗎?●程序員修神之路--高并發下為什么更喜歡進程內緩存●程序員修神之路--高并發優雅的做限流
總結
以上是生活随笔為你收集整理的程序员修神之路--做好分库分表其实很难之二的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lock VS Monitor
- 下一篇: 关于WinForms的跨显示器DPI自适