1. 程式人生 > >關於資料庫表的水平拆分和垂直拆分

關於資料庫表的水平拆分和垂直拆分

最初知道水平垂直分表的時候是剛參加工作不久的時候,知道了這個概念,但是公司使用者量和資料量始終沒上來,所以也沒用到過,知道有一天到了一家新公司後,這些才被應用到實際開發中,這裡我就大概說說關於水平和垂直的拆分.

分表的概念還是比較好理解的,就拿本網站的評論表展開講講,源於資料量較大,當評論表有CURD操作時,單張表表現的可能有些力不從心,當然這裡還能引申出關於讀寫速度的其他好多概念:資料庫讀寫分離,NoSql等等.

垂直拆分:
顧名思義是將表垂直著給拆掉,即:(下面是省略掉欄位的一個表)
  1. +--------+---------+--------+--------+-------+---------+---------+--------+-----+-------------+--------+-----------+------+--------+ 
  2. | userid | groupid | areaid | amount | point | modelid | message | islock | vip | overduedate | siteid | connectid | from | mobile | 
  3. +--------+---------+--------+--------+-------+---------+---------+--------+-----+-------------+--------+-----------+------+--------+ 
  4. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |      0 |   1 |           0 |      1 |           |      |        | 
  5. +--------+---------+--------+--------+-------+---------+---------+--------+-----+-------------+--------+-----------+------+--------+ 

比如說一個使用者表有很多的屬性,關聯了很多資料,如果放到同一個表裡面的話查詢是方便了,但是效率不行,所以這裡就是用到了垂直拆表:
拆成如下:

  1. +--------+---------+--------+--------+-------+---------+---------+
  2. | userid | groupid | areaid | amount | point | modelid | message |
  3. +--------+---------+--------+--------+-------+---------+---------+ 
  4. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |   
  5. +--------+---------+--------+--------+-------+---------+---------+
  6. 和 
  7. +--------+--------+-----+-------------+--------+-----------+------+--------+ 
  8. | userid | islock | vip | overduedate | siteid | connectid | from | mobile | 
  9. +--------+--------+-----+-------------+--------+-----------+------+--------+ 
  10. |      1 |      0 |   1 |           0 |      1 |           |      |        | 
  11. +--------+--------+-----+-------------+--------+-----------+------+--------+ 
  • 把常用的欄位放一個表,不常用的放一個表
  • 把欄位比較大的比如text的欄位拆出來放一個表裡面
  • 使用的話是根據具體業務來拆,查詢時使用多表聯查,可以再配合redis儲存
水平拆分:
顧名思義是將表資料水平的拆掉,即:
  1. 表0 user_0 
  2. +--------+---------+--------+--------+-------+---------+---------+ 
  3. | userid | groupid | areaid | amount | point | modelid | message | 
  4. +--------+---------+--------+--------+-------+---------+---------+ 
  5. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |   
  6. +--------+---------+--------+--------+-------+---------+---------+ 
  7. 表1 user_1 
  8. +--------+---------+--------+--------+-------+---------+---------+ 
  9. | userid | groupid | areaid | amount | point | modelid | message | 
  10. +--------+---------+--------+--------+-------+---------+---------+ 
  11. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |   
  12. +--------+---------+--------+--------+-------+---------+---------+ 
  13. 表2 user_2 
  14. +--------+---------+--------+--------+-------+---------+---------+ 
  15. | userid | groupid | areaid | amount | point | modelid | message | 
  16. +--------+---------+--------+--------+-------+---------+---------+ 
  17. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |   
  18. +--------+---------+--------+--------+-------+---------+---------+ 
  19. 表9 user_9 
  20. +--------+---------+--------+--------+-------+---------+---------+ 
  21. | userid | groupid | areaid | amount | point | modelid | message | 
  22. +--------+---------+--------+--------+-------+---------+---------+ 
  23. |      1 |       5 |      0 |   0.00 |    50 |      10 |       0 |   
  24. +--------+---------+--------+--------+-------+---------+---------+ 
當然這裡不一定要0-9一共10張表來表示,通常情況下使用"取模"的形式來將資料進行表的儲存,如果用4張表那麼就是id%4 結果會是0,1,2,3四種,user_0,user_1,user_2,user_3就夠了,具體這裡就要看錶的資料量了.
對水平分表的資料進行CURD操作也是一樣,之前根據id取模算出當前資料在哪張表中,然後再select * from user_"取的模",這裡有人要問了,我新增資料之前都不知道資料庫的id,更不能進行取模了,怎麼找到對應的表新增啊,對了,這裡就需要一張臨時表,臨時表的作用就是提供資料插入的自增id,得到自增id後再通過取模進行分表插入.
水平分表的表結構是一樣的,只是去掉了自增的屬性.

這裡不得不說水平分表的另一種形式,就是不是通過取模計算的分表,而是user_0存數10w條資料,存滿建立新表user_1,繼續儲存在user_1,存滿建立user_2一直儲存並新建下去,個人建議這種分表使用場景是user_1的資料為歷史資料,訪問需求量會慢慢減小,而新表的資料訪問量是很高的.

在這裡我想說的就是:"根據業務需求進行分表,不為業務服務的架構都是耍流氓".

原文部落格連結:http://www.yigangwu.com/index.php?m=content&c=index&a=show&catid=33&id=59  點選開啟連結