資料庫垂直拆分水平拆分
A. 關於資料庫的水平分割和垂直分割的幾點介紹
水平切分估計是指按照時間切分,垂直切分是指按照設備ID切分,這樣切分後,設備的狀態日誌會以記錄的形式存儲在不同的數據文件中,資料庫對這些文件的訪問可以通過設備ID和時間快速地查找到。而且應用中只是存儲日誌數據,不需要進行頻繁的實時查詢和統計,所以基本上資料庫的任務就是接收數據,寫入到文件中,文件對應的分片滿了就再創建新的分片文件。這樣整體的性能沒有任何變化,系統的負載也是維持在一個常量的水平。
如果要對日誌進行統計和分析,則會隨著日誌數量增加,性能顯著下降,但這里沒有這樣的需求,即使有,也是用另外一組離線分析伺服器進行處理。
B. 淺談mysql資料庫分庫分表那些事-億級數據存儲方案
mysql分庫分表一般有如下場景
其中1,2相對較容易實現,本文重點講講水平拆表和水平拆庫,以及基於mybatis插件方式實現水平拆分方案寬兄落地。
在 《聊一聊擴展欄位設計》 一文中有講解到基於KV水平存儲擴展欄位方案,這就是非常典型的可以水平分表的場景。主表和kv表是一對N關系,隨著主表數據量增長,KV表最大N倍線性增長。
這里我們以分KV表水平拆分為場景
對於kv擴展欄位查詢,只會根據id + key 或者 id 為條件的方式查詢,所以這里我們可以按照id 分片即可
分512張表(實際場景具體分多少表還得根據欄位增加的頻次而定)
分表後表名為kv_000 ~ kv_511
id % 512 = 1 .... 分到 kv_001,
id % 512 = 2 .... 分到 kv_002
依次類推!
水平分表相對比較容易,後面會講到基於mybatis插件實現方案
場景:以下我們基於博客文章表分庫場景來分析
目標:
表結構如下(節選部分欄位):
按照user_id sharding
假如分1024個庫,按照user_id % 1024 hash
user_id % 1024 = 1 分到db_001庫
user_id % 1024 = 2 分到db_002庫
依次類推
目前是2個節點,假如後期達到瓶頸,我們可以增加至4個節點
最多可以增加只1024個節點,性能線性增長
對於水平分表/分庫後,非shardingKey查詢首先得考慮到
基於mybatis分庫分表,一般常用的一種是基於spring AOP方式, 另外一種基於mybatis插件。其實兩種方式思路差不多。
為了比較直觀解決這個問題,我分別在Executor 和StatementHandler階段2個晌陵攔截器
實現動態數據源慎謹襲獲取介面
測試結果如下
由此可知,我們需要在Executor階段 切換數據源
對於分庫:
原始sql:
目標sql:
其中定義了三個註解
@useMaster 是否強制讀主
@shardingBy 分片標識
@DB 定義邏輯表名 庫名以及分片策略
1)編寫entity
Insert
select
以上順利實現mysql分庫,同樣的道理實現同時分庫分表也很容易實現。
此插件具體實現方案已開源: https://github.com/bytearch/mybatis-sharding
目錄如下:
mysql分庫分表,首先得找到瓶頸在哪裡(IO or CPU),是分庫還是分表,分多少?不能為了分庫分表而拆分。
原則上是盡量先垂直拆分 後 水平拆分。
以上基於mybatis插件分庫分表是一種實現思路,還有很多不完善的地方,
例如:
C. 資料庫水平拆分和垂直拆分 怎麼實現
垂直拆分
垂直拆分是指數據表列的拆分,把一張列比較多的表拆分為多張表
通常我們按以下原則進行垂直拆分:
把不常用的欄位單獨放在一張表;
把text,blob等大欄位拆分出來放在附表中;
經常組合查詢的列放在一張表中;垂直拆分更多時候就應該在數據表設計之初就執行的步驟,然後查詢的時候用join關鍵起來即可;
水平拆分
水平拆分是指數據錶行的拆分,表的行數超過200萬行時,就會變慢,這時可以把一張的表的數據拆成多張表來存放。
水平拆分的一些技巧
1. 拆分原則
通常情況下,我們使用取模的方式來進行表的拆分;比如一張有400W的用戶表users,為提高其查詢效率我們把其分成4張表
users1,users2,users3,users4
通過用ID取模的方法把數據分散到四張表內Id%4+1 = [1,2,3,4]
這里是個小哈希,然後查詢,更新,刪除也是通過取模的方法來查詢
$_GET['id'] = 17,
17%4 + 1 = 2,
$tableName = 'users'.'2'
Select * from users2 where id = 17;
在insert時還需要一張臨時表uid_temp來提供自增的ID,該表的唯一用處就是提供自增的ID;
insert into uid_temp values(null);
得到自增的ID後,又通過取模法進行分表插入;
注意,進行水平拆分後的表,欄位的列和類型和原表應該是相同的,但是要記得去掉auto_increment自增長
另外
部分業務邏輯也可以通過地區,年份等欄位來進行歸檔拆分;
進行拆分後的表,只能滿足部分查詢的高效查詢需求,這時我們就要在產品策劃上,從界面上約束用戶查詢行為。比如我們是按年來進行歸檔拆分的,這個時候在頁面設計上就約束用戶必須要先選擇年,然後才能進行查詢;
在做分析或者統計時,由於是自己人的需求,多點等待其實是沒關系的,並且並發很低,這個時候可以用union把所有表都組合成一張視圖來進行查詢,然後再進行查詢;
Create view users as select from users1 union select from users2 union.........
D. 整個資料庫的dmp文件能拆分出表嗎
可以。
數據的切分(Sharding)根據其切分規則的類型,可以分為兩種切分模式。一種是按照不同的表(或Schema)來切分到不同的資料庫(主機)之上,這種切可以稱之為數據的垂直(縱向)切分,另外一種則是根據表中的數據的邏輯關系,將同一個表中的數據按照某種條件拆分到多台資料庫(主機)上面,這種切分稱之為數據的水平(橫向)切分。垂直切分一個資料庫由很多表的構成,每個表對應著不同的業務,垂直切分是指按照業務將表進行分類,分布到不同的資料庫上面,這樣也就將數據或者說壓力分擔到不同的庫上面, 垂直切分的優缺點介紹:
優點:拆分後業務清晰,拆分規則明確。系統之間整合或擴展容易。數據維護簡單。
缺點:部分業務表無法join,只能通過介面方式解決,提高了系統復雜度。受每種業務不同的限制存在單庫性能瓶頸,不易數據擴展跟性能提高。事務處理復雜。由於垂直切分是按照業務的分類將表分散到不同的庫,所以有些業務表會過於龐大,存在單庫讀寫與存儲瓶頸,所以就需要水平拆分來做解決。水平切分相對於垂直拆分,水平拆分不是將表做分類,而是按照某個欄位的某種規則來分散到多個庫之中,每個表中包含一部分數據。簡單來說,我們可以將數據的水平切分理解為是按照數據行的切分,就是將表中的某些行切分到一個資料庫,而另外的某些行又切分到其他的資料庫中,水平切分的優缺點介紹:拆分規則抽象好,join操作基本可以資料庫做。
不存在單庫大數據,高並發的性能瓶頸。應用端改造較少。提高了系統的穩定性跟負載能力。拆分規則難以抽象。分片事務一致性難以解決。數據多次擴展難度跟維護量極大。跨庫join性能較差。垂直切分和水平切分共同的特點和缺點有:引入分布式事務的問題。跨節點Join的問題。跨節點合並排序分頁問題。多數據源管理問題。
E. 資料庫水平拆分是在單庫中拆出多個表,每個表是表名+規則。還是分出多個庫,每個庫是庫名+規則,表名不變
1 基本思想之什麼是分庫分表?
從字面上簡單理解,就是把原本存儲於一個庫的數據分塊存儲到多個庫上,把原本存儲於一個表的數據分塊存儲到多個表上。
2 基本思想之為什麼要分庫分表?
資料庫中的數據量不一定是可控的,在未進行分庫分表的情況下,隨著時間和業務的發展,庫中的表會越來越多,表中的數據量也會越來越大,相應地,數據操作,增刪改查的開銷也會越來越大;另外,由於無法進行分布式式部署,而一台伺服器的資源(CPU、磁碟、內存、IO等)是有限的,最終資料庫所能承載的數據量、數據處理能力都將遭遇瓶頸。
3 分庫分表的實施策略。
分庫分表有垂直切分和水平切分兩種。
3.1 何謂垂直切分,即將表按照功能模塊、關系密切程度劃分出來,部署到不同的庫上。例如,我們會建立定義資料庫workDB、商品資料庫payDB、用戶資料庫userDB、日誌資料庫logDB等,分別用於存儲項目數據定義表、商品定義表、用戶數據表、日誌數據表等。
3.2 何謂水平切分,當一個表中的數據量過大時,我們可以把該表的數據按照某種規則,例如userID散列,進行劃分,然後存儲到多個結構相同的表,和不同的庫上。例如,我們的userDB中的用戶數據表中,每一個表的數據量都很大,就可以把userDB切分為結構相同的多個userDB:part0DB、part1DB等,再將userDB上的用戶數據表userTable,切分為很多userTable:userTable0、userTable1等,然後將這些表按照一定的規則存儲到多個userDB上。
3.3 應該使用哪一種方式來實施資料庫分庫分表,這要看資料庫中數據量的瓶頸所在,並綜合項目的業務類型進行考慮。
如果資料庫是因為表太多而造成海量數據,並且項目的各項業務邏輯劃分清晰、低耦合,那麼規則簡單明了、容易實施的垂直切分必是首選。
而如果資料庫中的表並不多,但單表的數據量很大、或數據熱度很高,這種情況之下就應該選擇水平切分,水平切分比垂直切分要復雜一些,它將原本邏輯上屬於一體的數據進行了物理分割,除了在分割時要對分割的粒度做好評估,考慮數據平均和負載平均,後期也將對項目人員及應用程序產生額外的數據管理負擔。
在現實項目中,往往是這兩種情況兼而有之,這就需要做出權衡,甚至既需要垂直切分,又需要水平切分。我們的游戲項目便綜合使用了垂直與水平切分,我們首先對資料庫進行垂直切分,然後,再針對一部分表,通常是用戶數據表,進行水平切分。
F. 資料庫水平分庫和垂直分庫有什麼區別
常見的分庫方式有水平性和垂直性。一般來說,就是按照用戶屬性(地市或者ID的hash)進行分庫,或者按照業務功能塊進行分庫。
水平分庫方式主要根據用戶屬性(如地市)拆分物理資料庫。一種常見的方式是將全省劃分為個大區。
垂直分庫方式:根據業務維度和數據的訪問量等,進行數據的分離,剝離為多個資料庫。例如,將一些公用的配置信息存儲到一個資料庫中進行單獨維護。