問題描述
為什么進行分表? 分庫?
一般多少數據量開始分表?
什么是數據庫垂直拆分和水平拆分
回答
為什么要進行分庫
業務發展,當單個數據庫中的表越來越多,數據量越來越大的時候。數據的增刪改查所消耗的資源就會增加。由于mysql是無法分布式部署(可能會有人說不是有主從嗎?并不是,詳細會在其他文章說明)的。==而單臺服務器的資源,如CPU、磁盤、內存、IO等都是有限的。最終數據庫所承載的數據量和處理數據的能力就會遇到瓶頸==。此時有兩種解決方案:
橫向擴展
縱向擴展
縱向擴展就是增加單臺服務器的性能,如升級cpu,內存,磁盤換ssd等,這是最簡單的方案,但是也是最燒錢的。
橫向擴展就是對數據進行拆分,放置到多臺服務器(相對廉價的服務器)上。對數據進行拆分,一般是對數據進行合理的分庫,再對分離出來的庫進行調優。即將單臺服務器上的壓力分布到多臺機器中。這就是分庫的理由
為什么進行分表
當MySQL的單表的數據達到一定量級的時候(如一千萬)的時候,就需要考慮進行分表。因為此時的MySQL的執行性能就會下降(這和mysql本身的實現機制有關)。簡單來講有如下兩個原因
- 鎖機制
為了保證數據的完整性,數據庫有鎖定機制。MySQL中有表鎖定和行鎖定,MySQL中myisam存儲引擎是表鎖定,innodb存儲引擎是行鎖定。分為包含共享鎖和獨占鎖兩種。獨占鎖就是整個數據文件歸一個線程所有,其他線程就必須等待。==如果數據太多,一次執行的時間太長==,特別是在鎖表的情況下,就會導致大量的其他SQL等待執行,嚴重影響系統的正常使用。
- 索引更新
更新表數據時會導致索引更新,當單表數據量很大時這個過程比較耗時,這就是為什么對大表進行新增操作會比較慢的原因。并且更新表數據會進行表級鎖或者行鎖,這樣就導致其他操作等待。
所以我們將大表拆分為多個字表,那么在更新或者查詢數據的時候,壓力會分散到不同的表上。由于分表之后每個表的數據較小,不管是查詢還是更新都極大的提高了速度,即使出現最壞的“鎖表”的情況,那其他表還是可以并行使用。
一般多少數據量開始分表
這個問題沒有一個固定的答案,需要根據表的用途和業務來要求來評估此數據量。但是,當mysql的數據量達到千萬級別的時候,就需要考慮是否需要進行分表操作。以下幾個是一些參考因素:
寫入量(高峰期寫入量,是否會造成鎖表導致讀或者寫出現一些問題,insert,update,delete的比例各多少)
查詢量(查詢量多大,是否跟寫會造成相互影響)
查詢方式(單記錄查詢,還是多記錄查詢,是否有count查詢,比重各占多少,每次返回的記錄數數量級1,10,100,1000 。。。)
是否有分頁(重點關注,是否存在大分頁)
1,2 算是比較基礎的,正常1kw以下都沒太大問題。3,4 受單表數據量的影響起始更小,但是反過來,這個就直接影響到 1,2
不同的情形,數據量的規模不太一樣。例如,單表只有insert和單條查詢的,每天增長百萬數據,這種億的規模問題都不大,當然能拆最好~
有簡單 in 查詢的,這種也能夠接受~ 但是如果有比較大的查詢,或者比較復雜的,包括大分頁,然后還有大量的 update的,這種表就不能太大,正常不要超過 300w~
==update 的頻率,應該算是里面影響比較大的因素==,insert一般只添加數據,不會對查詢造成太多影響但是update和 select 可能就會有比較大的相互影響了~
什么是垂直拆分和水平拆分
垂直拆分是指數據表列的拆分,把一張列比較多的表拆分為多張表 或者 將表按模塊劃分到不同數據庫表中(分庫或者拆表)
水平拆分是指數據表行的拆分,比如表的行數超過200萬行時,就會變慢,這時可以把一張的表的數據拆成多張表來存放==(分表)==。