mysql分庫分割槽分表
分表:
分表分為水平分表和垂直分表。
水平分表原理:
分表策略通常是使用者ID取模,如果不是整數,可以首先將其進行hash獲取到整。
水平分表遇到的問題:
1. 跨表直接連線查詢無法進行
2. 我們需要統計資料的時候
3. 如果資料持續增長,達到現有分表的瓶頸,需要增加分表,此時會出現資料重新排列的情況
解決方案建議:
1. 第1,2點可以通過增加彙總的冗餘表,雖然資料量很大,但是可以用於後臺統計或者查詢時效性比較底的情況,而且我們可以提前算好某個時間點或者時間段的資料
2. 第3點解決建議:
1. 可以開始的時候,就分析大概的資料增長率,來大概確定未來某段時間內的資料總量,從而提前計算出未來某段時間內需要用到的分表的個數
2. 考慮表分割槽,在邏輯上面還是一個表名,實際物理儲存在不同的實體地址上
3. 分庫
垂直拆分原則:
1. 把大欄位獨立儲存到一張表中
2. 把不常用的欄位單獨拿出來儲存到一張表
3. 把經常在一起使用的欄位可以拿出來單獨儲存到一張表
垂直拆分標準:
1.表的體積大於2G並且行數大於1千萬
2.表中包含有text,blob,varchar(1000)以上
3.資料有時效性的,可以單獨拿出來歸檔處理
/*表的體積計算*/
CREATE TABLE `test1` (
id bigint(20) not null auto_increment,
detail varchar(2000),
createtime datetime,
validity int default '0',
primary key (id)
);
1000萬 bigint 8位元組 varchar 2000 位元組 datetime 8位元組 validity 4位元組
(8+2000+8+4) * 10000000 = 20200000000 位元組 == 18G
分表後體積:
CREATE TABLE `test1` (
id int not null auto_increment,
createtime timestamp,
validity tinyint default 0,
primary key (id)
);
(4+4+1) * 10000000 = 0.08G
分庫策略與分表策略的實現很相似,最簡單的都是可以通過取模的方式進行路由。
分庫也可以按照業務分庫,比如訂單表和庫存表在兩個庫,要注意處理好跨庫事務。
分表和分庫 同時實現。
分庫分表的策略相對於前邊兩種複雜一些,一種常見的路由策略如下:
1、中間變數 = user_id%(庫數量*每個庫的表數量);
2、庫序號 = 取整(中間變數/每個庫的表數量);
3、表序號 = 中間變數%每個庫的表數量;
例如:資料庫有256 個,每一個庫中有1024個數據表,使用者的user_id=262145,按照上述的路由策略,可得:
1、中間變數 = 262145%(256*1024)= 1;
2、庫序號 = 取整(1/1024)= 0;
3、表序號 = 1%1024 = 1;
這樣的話,對於user_id=262145,將被路由到第0個數據庫的第1個表中。
表分割槽:
就是將一個數據量比較大的表,用某種方法把資料從物理上分成若干個小表來儲存(類似水平分表),從邏輯來看還是一個大表。分表最大分1024,一般分100左右比較適合。
使用場景:
對於這種資料庫比較多,但是併發不是很多的情況下,可以採用表分割槽。
對於資料量比較大的,但是併發也比較高的情況下,可以採用分表和分割槽相結合。
/*range分割槽*/
create table test_range(
id int not null default 0
)engine=myisam default charset=utf8
partition by range(id)(
partition p1 values less than (3),
partition p2 values less than (5),
partition p3 values less than maxvalue
);
/*hash分割槽*/
create table test_hash(
id int not null default 0
)engine=innodb default charset=utf8
partition by hash(id) partitions 10;
/*線性hash分割槽*/
create table test_linear(
id int not null default 0
)engine=innodb default charset=utf8
partition by linear hash(id) partitions 10;
/* list分割槽*/
create table test_list(
id int not null
) engine=innodb default charset=utf8
partition by list(id)(
partition p0 values in (3,5),
partition p1 values in (2,6,7,9)
);
/* key 分割槽 */
CREATE TABLE test_key (
col1 INT NOT NULL
)
PARTITION BY linear KEY (col1)
PARTITIONS 10;
普通的hash分割槽 增加風區後,需要重新計算
線性hash分割槽(瞭解) 增加分割槽後,還是在原來的分割槽
線性hash 相對於 hash分割槽 沒有那麼均勻
Key分割槽用的比較少,也是hash分割槽
分類: