数据库拆分:横向拆分和纵向拆分
1、水平分割:
按記錄進分分割,不同的記錄可以分開保存,每個子表的列數相同。
水平分割通常在下面的情況下使用:
A 表很大,分割后可以降低在查詢時需要讀的數據和索引的頁數,同時也降低了索引的層數,提高查詢速度。
B 表中的數據本來就有獨立性,例如表中分別記錄各個地區的數據或不同時期的數據,特別是有些數據常用,而另外一些數據不常用。
C需要把數據存放到多個介質上。
例如法規表law就可以分成兩個表active-law和 inactive-law。activea-authors表中的內容是正生效的法規,是經常使用的,而inactive-law表則使已經作廢的法規,不常被查詢。水平分割會給應用增加復雜度,它通常在查詢時需要多個表名,查詢所有數據需要union操作。在許多數據庫應用中,這種復雜性會超過它帶來的優點,因為只要索引關鍵字不大,則在索引用于查詢時,表中增加兩到三倍數據量,查詢時也就增加讀一個索引層的磁盤次數。
2、垂直分割:
按列進行分割,即把一條記錄分開多個地方保存,每個子表的行數相同。
把主碼和一些列放到一個表,然后把主碼和另外的列放到另一個表中。如果一個表中某些列常用,而另外一些列不常用,則可以采用垂直分割,另外垂直分割可以使得數據行變小,一個數據頁就能存放更多的數據,在查詢時就會減少I/O 次數。其缺點是需要管理冗余列,查詢所有數據需要join操作。
例如有表T1
id name qty
--------------
1 p1 10
2 p2 20
3 p3 30
4 p4 40
......
......
垂直分割就是按列進行分割,即把一條記錄分開多個地方保存,每個子表的行數相同。
例如表T1,可以把id和name放到數據文件p1,把qty放到數據文件p2。
水平分割就是按記錄進分分割,不同的記錄可以分開保存,每個子表的列數相同。
像表T1,可以把id為單數的放到數據文件P1,雙數的放到數據文件P2。
淘寶下單是在一個數據庫事務中進行的,要提高數據庫的事務并發數,最有效的辦法是拆分,拆分有兩種,一是對庫進行拆分,另一種是在同一個庫中對表進行拆分。
要做拆分首先就要考慮拆分依據的字段,淘寶是根據訂單號做拆分的,而下單中有兩個維度,買家和賣家,對訂單做拆分之后,必須還是可以通過買家,賣家方便的查詢著兩個維度的數據。該怎么辦呢?
這里留個疑問,我先介紹淘寶拆分的規模,淘寶將訂單表拆分到16個mysql庫中,而在每個庫中又將訂單表橫向拆分為64份,相當于將一個表拆分為1024份。拆分之后事務會分散到1024套表中,這必然會很大程序上增加并發的事務處理能力(這兒我說是必然,但是淘寶在使用這種方案之前是要經過壓力測試,實際測試出這種方案的TPS之后,才會逐步采用這種方案的)。
上面留了一個疑問,經過拆分之后如何保證買家賣家快速的查詢其下的訂單呢?最好的辦法是保證買家和賣家下的訂單在一張表中,如何保證呢?
淘寶的做法是將買家的id取模后放到訂單號中。假定一個訂單號是142424594267667;
對于16臺服務器,每臺服務器64張表只需要2位買家或賣家id的后兩位數字就可以準確定位到具體的庫和表。訂單號中同時存在買家id的最后兩位和賣家id的最后兩位。分別在訂單號的倒數第3,4位數和最后兩位數。
假定買家id為123456789,那么在訂單號中的最后兩位就是89,通過89對16取模就可以定位到具體的庫上,通過對64取模就可以定位到具體的表上。
總結
以上是生活随笔為你收集整理的数据库拆分:横向拆分和纵向拆分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c/c++ 网络编程 UDP 设定MT
- 下一篇: [转帖]EDID定义