联系邮箱:254200493@qq.com 登录 注册

MySQL分表及分区技术

2020-01-18 15:26:10

场景:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,则有可能会卡住。分表的目的就在于此,减小数据库的负担,缩短查询时间。
解决方法:1增加查询缓存;2使用分表技术;

查询缓存在这里就不提了,主要介绍MySQL分表的相关技术
分表的相关概念:

水平分表:创建多张表,通过程序算法判断对应id在哪张表;
例:表id%表数量,根据余数选择对应的数据表。
垂直分表:将表字段拆分到其他表中。
例:将表字段常用和不常用的拆分开,分别存放到不同的表;

水平分表、垂直分表虽然可以加快查询速度,但是逻辑比较复杂。特别是对旧项目的改造,就显得更加麻烦。这里我们可以使用分区技术,由MySQL底层实现水平分表,我们在应用层还是写原生SQL语句即可。

下面介绍四种MySQL分区算法

create table 表名名(
表字段列表
)engine=存储引擎 charset=编号
partition by 算法名(字段) partitions 分区数量;

求余(主键字段):key算法、hash算法
条件:list数据必须在指定集合中,range数据在执行范围中
1、key分区

create table articles(
id int(10) unsigned primary key auto_increment,
title varchar(50) not null,
content text
) engine = InnoDB charset = utf8
partition by key(id) partitions 3;

2、hash 分区

create table articles(
id int(10) unsigned primary key auto_increment,
title varchar(50) not null,
content text
) engine = InnoDB charset = utf8
partition by hash(id) partitions 3;

3、list 分区

create table articles(
id int(10) unsigned auto_increment,
cid int(10) unsigned,
title varchar(50) not null,
content text,
primary key(id,cid) #主键必须包含cid
) engine = InnoDB charset = utf8
partition by list(cid)(
partition c1 values in (1,3),
partition c2 values in (2,4),
partition c3 values in (5,6,7)
);

4、range 分区

create table students(
id int(10) unsigned auto_increment,
name varchar(16) not null,
birthday date not null,
primary key(id,birthday) #主键必须包含birthday
) engine = InnoDB charset = utf8
partition by range(year(birthday)) (
partition 70hou values less than (1980),
partition 80hou values less than (1990),
partition 90hou values less than (2000),
partition 00hou values less than (2010)
);

3、分区管理
取余管理:增加分区数量不影响原数据,删除分区不影响原数据
条件管理:增加分区数量不影响原数据;删掉了某分区,则该分区内的数据将全部丢失,用show create table members\G;命令查看该表的创建语句时将无法看到被删除分区的任何信息。
(1)key、hash
增加分区数量:alter table 表名 add partition partitions 个数
减少分区数量:alter table 表名 coalesce partition 个数

(2)list、range
删除分区:alter table 表名 drop partition 分区名;
如果只是删除数据而不删除该分区的信息,可使用truncate命令
alter table 表名 truncate partition 分区名称;
list添加分区

alter table 表名 add partition(
partition 分区名 values in (8,9,10)
);

range添加分区

alter table 表名 add partition(
partition 分区名 values less than (maxvalue)
);



相关文章