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分區


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM