mysql 取模分区_Mysql进阶之分区

===================================

原文链接:
https://blog.csdn.net/weixin_39860583/article/details/113438389

====

分区

先复习一下Myisam和InnoDB这两种引擎的文件存储格式:

Myisam:

frm 存表结构的文件

MYD 存表数据的文件

MYI 存索引的文件

Innodb:

frm 存表结构的文件

ibd 存表数据的文件

Innodb又分为两种:共享表空间和独享表空间

从mysql 5.6.6版本开始,独立表空间(file-per-table tablespaces)默认是开启的(也就是innodb_file_per_table参数不设置时,它默认等于1),而mysql5.5以前默认设置是共享表空间,使用表分区功能前先要检查
innodb_file_per_table是否开启。

共享表空间就是一个库的所有表都放在一个文件中,如ibddata1这个文件就是共享表空间。

独享表空间就是一个表单独放在一个文件中。

很明显,独享表空间的性能更高。

show variables like “%innodb_file_per_table%”;

这个参数为ON表示使用独享表空间。

分表的情况是

tb_1 对应 文件1(包含结构文件和数据文件)

tb_2 对应 文件2(包含结构文件和数据文件)

tb_3 对应 文件3(包含结构文件和数据文件)

数据插入哪个表或者数据查询从哪个表查,我们要在业务层自己写算法来判断

分区的情况是(假如分区为3个区)

文件1

tb 对应 文件2

文件3

分成几个区,就会生成几个文件,但是表还是1个表。

而算法和策略不需要再业务层自己实现,而是mysql内部实现。

常见分区的策略有4种:

Range:如id为1100的数据存放到第一个分区,101200放到第二个分区,…依次类推(以连续型数据字段作为分区的字段)

List:如分类A的数据放到第一个分区,B分类的数据放第二个分区,…以此类推(以离散型数据字段作为分区字段)

Hash:使用表达式作为分区标准, 如对字段取模,将模相同的数据放到相同分区

Key:和Hash类似,可以对某字段使用表达式作为分区标准。这个和Hash本质还是一样的。

重点是前3个。

PS:建立分区的字段必须是主键字段或者被包含在主键字段(如复合主键)中。例子如下:

在test库先建立一个普通的表:

create table t_base(id int primary key auto_increment,name varchar(10))engine=innodb;

insert into t_base (name) values (“zbp”);

insert into t_base (name) select name from t_base; # 蠕虫复制400多万条数据。

select count(*) from t_base; # 4194304

更改他们的name字段为随机的数字

update t_base set name=ceil(rand()*5000000);

现在mysql存放数据的目录的test目录中可以看到t_baes.ibd(290M)和t_base.frm文件


创建range分区的表

create table t_range(

id int primary key auto_increment,

name varchar(10)

)engine=innodb partition by range(id)(

partition p0 values less than (1000000), # p0是分区名

partition p1 values less than (2000000),

partition p2 values less than (3000000),

partition p3 values less than (4000000),

partition p4 values less than (5000000) #可使用maxvalue关键字表示最大的id数

);

此时会出现t_range#p#p0~4.ibd这4个表数据文件和一个t_range.frm表结构文件。

将t_base数据写入t_range中

insert into t_range select * from t_base;

PS,如果删除某个分区,该分区下的数据会被删掉。

alter table t_range drop partition p4;

查看分区情况

show create table t_range;


创建List分区,List分区字段必须是int型,不能是字符串型

create table t_list(

id int auto_increment,

type_id int ,

name varchar(20),

primary key (id,type_id)

)engine=innodb partition by list(type_id)(

partition p0 values in (1,2,3),

partition p1 values in (4),

partition p2 values in (5,6)

);

往t_list中插入500万数据

insert into t_list (id,type_id,name) select id,ceil(rand()*6) type_id,name from t_base;


创建hash分区,要指定分区个数,生成的4个表数据文件是一样大的,因为hash分区方式会将数据平均分配到每个分区,其实是取模算法。

create table t_hash(

id int primary key auto_increment,

name varchar(10)

)engine=innodb partition by hash(id) partitions 4;

指定创建4个分区,对id进行4的取模

select * from t_hash limit 10; # 从第一个分区获取10条数据,第一个分区是模为0的分区,故得到的id都是4的倍数


PS 如果只想移除分区但不想删除数据可以使用

alter table xxx remove partitioning;

但会删除所有分区

作者不推荐使用分区,因为mysql 5.7版本以前的分区功能有比较大不稳定性,可能造成比较严重的性能问题。

更多关于分区的操作如合并分区,修改分区可参考网上资料

=======================================

Guess you like

Origin blog.csdn.net/m0_37866091/article/details/120953018