首页 > 代码库 > mysql分表和分区简述

mysql分表和分区简述

1)分表
目的:提升对海量数据的进行存取操作的效率
选择合适的分表策略,确定分表策略后,当进行数据存取操作时,需求确定要到那张表里去查询数据
分表字段:互联网的系统使用用户id字段
数据是放到哪个表:分表的字段%分表的数量
策略:
根据范围分区(表ID 1~200 db1 表ID 201~200 db2 表ID m~n dbn)
范围应该连续但是不连续,使用PAPRTION BY RANGE VALUES LESS THAN关键字
不使用COLUMNS关键字时,RANGE中必须为整数字段名或返回确定整数字段的函数
使用columns关键字,可定义非integer范围及多列范围,columns中只能是列名,多列范围必须呈递增趋势
哈希拆分(表 ID%db数量 db取模)
根据配置文件来分表

范围分区例子:
1)根据数值字段分区
CREATE TABLE test (
id INT NOT NULL,
testid INT NOT NULL
)
PARTITION BY RANGE (testid) (
PARTITION p0 VALUES LESS THAN (100000),
PARTITION p1 VALUES LESS THAN (200000),
PARTITION p2 VALUES LESS THAN (300000),
PARTITION p3 VALUES LESS THAN MAXVALUE
);

2)根据时间字段(timestamp)分区
create table testb (
id bigint unsigned not null,
updated_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
partition by range (unix_timestamp(updated_time) ) (
partition p0 values less than (unix_timestamp(‘2017-01-01 00:00:00‘)),
partition p1 values less than (unix_timestamp(‘2017-03-01 00:00:00‘)),
partition p2 values less than (unix_timestamp(‘2017-06-01 00:00:00‘)),
partition p3 values less than (maxvalue)
);

3)根据时间字段(date datetime)分区
create table testc (
id bigint unsigned not null,
updated_time datetime not null
)
partition by range columns(updated_time) (
partition p0 values less than (‘2017-01-01 00:00:00‘),
partition p1 values less than (‘2017-03-01 00:00:00‘),
partition p2 values less than (‘2017-06-01 00:00:00‘),
partition p3 values less than (maxvalue)
);

4)根据多个字段分区
create table testd (
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by range columns(region,statu) (
partition p0 values less than (1000100,1),
partition p1 values less than (2000100,2),
partition p2 values less than (3000100,3),
partition p3 values less than (4000100,4),
partition p4 values less than (maxvalue,maxvalue)
);

list分区
根据具体数值分区,每个分区值不能重复,使用partiton by list values in关键字
不使用COLUMNS关键字时,list中必须为整数字段名或返回确定整数字段的函数
create table teste(
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by list columns(statu) (
partition p0 values in (1,3,5),
partition p1 values in (2,4,6),
partition p2 values in (7,8,9),
partition p3 values in (0,10)
);

hash分区
在确定的数目分区中平均分布,hash必须为整数字段名或返回确定整数字段的函数
create table testf(
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by hash(statu)
partitions 4;

create table testg(
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by linear hash(statu)
partitions 4;

key分区
表中存在主键或唯一索引时,可忽略key中的列名
create table testh1(
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by key(statu)
partitions 4;

create table testh2(
id bigint unsigned not null,
region int not null,
statu smallint not null
)
partition by linear key(statu)
partitions 4;

子分区
对分区表中每个分区再进行分区,每个分区的子分区数必须相同,子分区在全表中名字唯一
CREATE TABLE testf1 (id int, updated_time date)
PARTITION BY RANGE(year(updated_time) )
SUBPARTITION BY hash(TO_DAYS(updated_time))
SUBPARTITIONS 1 (
PARTITION p0 VALUES LESS THAN (1949),
PARTITION p1 VALUES LESS THAN (1959),
PARTITION p2 VALUES LESS THAN (1969),
PARTITION p3 VALUES LESS THAN (1979),
PARTITION p4 VALUES LESS THAN (1989),
PARTITION p5 VALUES LESS THAN (1999),
PARTITION p6 VALUES LESS THAN (2009),
PARTITION p7 VALUES LESS THAN (2019),
PARTITION p8 VALUES LESS THAN MAXVALUE
);


2)分库
目的:降低对海量数据的进行高并发现象的几率
数据是放到哪个库:分库的字段%数据库的数量

3)分表后分库
目的:同时提升存储效率和降低高并发现象
中间变量:关键字段(userid)%(数据库数量*每个库的表数量)
库序号:取整:中间变量/每个库的表数量
表序号:取余:中间变量/每个库的表数量

假设数据库有100个,每1个库有256张表,用户的userid=28800,按照上面策略,则:
中间变量:28800%(100*256)=1
库序号:取整 1/1024=0
表序号:取余 1/1024=1
因此,userid=28800的记录,会被存储到底0个库第1个表中。
4)空节点查询
一般查询:查询->到各个层级去查询,所有结果都不存在->再到数据库中查询->返回结果给前端
避免空节点查询:查询->直接到映射表(存在的记录)查询->再各个层级进行查询->再到数据库中查询
节点容灾或过载保护:当查询数据库时超过阈值后,数据库拒绝提供服务,将多余的请求分发到其他闲的节点上。

mysql分表和分区简述