一篇文章讲透mysql数据库下的分区表

3 篇文章 0 订阅
1 篇文章 0 订阅
  • 正确理解数据库分区表

  • 分区表的特征及分区类型

  • 分区表的应用场景

什么是分区表

分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中。 查询时可以通过查询表来访问各个分区中的数据,也可以通过在查询时直接指定分区的方法来进行查询。

 

首先来看下正常的表的存放方式

输入cd /var/lib/mysql/test_database/,再ls,查看数据库下的表(customer_login_log)文件信息:

 

customer_login_log.frm #保存了每个表的元数据,包括表结构以及相应的定义,无论什么数据引擎都有此文件

customer_login_log.ibd #innodb的存放数据文件和索引的地方

customer_login_log--表名

 

换引擎测试

 

分区表在:customer_login_log.idb上会有多个

  • 在mysql v5.1版本后就开始支持分区表功能

show variables like '%partition%';

  • mysql v5.6(含)版本下使用这个命令,看系统是否支持分区

show plugins;

        

    

我们为什么要使用分区表

  • 经常遇到上千万甚至上亿的记录表数据

  • 查询困难,而且历史数据其实是不太关心的

  • 要进行归档了,那么如何归档?

1. insert select:一年前的数据通过where<20190101 00:00:00查出来insert进arch,bak

2.dump方式:mysqldump是可以加where条件

原表的历史数据要删除,方式: 

1.delete方式:delete table where time< and time>,删除不要的

innodb数据是有b+树组织的,如果delete where只会标记该数据被删除,不会真正删除,将来

插入数据的时候空间可复用

mysql> optimize table my_table_name;

2.把要的数据导出,创建新表,不要的数据备份,旧表drop

  • 如果我们有这样一种文件组织形式:2017、2018数据单独都放一个文件,这个时候就可以按照文件进行

删除了,并且可以指定数据文件查询范围,就会提升查询效率

分区表都有哪些分区类型

  • HASH分区:按照hash算法分区

  • List分区:   

  • RANGE分区(重点):

  • KEY分区:

HASH分区

  • 根据MOD(分区键)的值把数据存储到表的不同分区中

  • 基本可以平均分布于各个区

  • HASH分区的键必须为整形,可以通过函数转换为int类型

create table test2(name varchar(5),age int(3)) ENGINE=InnoDb 

DEFAULT CHARSET=utf8 PARTITION BY HASH(age) PARTITIONS 4;  # 分成四个文件  age可以转换为函数方式

 

explain partitions select * from test2;#查看分区是否创建成功

 

select table_name,partition_name,partition_description,table_rows from information_schema.PARTITIONS where table_name='test2'; #每个分区存放多少数据 

 

select * from test2 partition(p1) where age=3#明确指定查询哪个分区

 

LIST分区

  • 按照分区键取值的列表进行分区

  • 各分区的列表值不能重复

  • 每一行数据必须能找到对应的分区列表,否则插入失败

 

create table test3(name varchar(5),age int(3)) ENGINE=InnoDb

DEFAULT CHARSET=utf8 PARTITION BY LIST(age) (PARTITION p0 VALUES in(1,3,5,7,9),PARTITION p1 VALUES in(2,4,6,8));  #分成两个文件 

 

RANGE范围分区

  • 根据分区键值保存到不同表中

  • 多个分区要连续,不能重叠

  • 要完全封口则需要使用MAXVALUE

create table test5(name varchar(5),age int(3),login_time dateTime) ENGINE=InnoDb

DEFAULT CHARSET=utf8 PARTITION BY RANGE(age) (PARTITION p0 VALUES LESS THAN (30),PARTITION p1 VALUES LESS THAN (50)

,PARTITION p2 VALUES LESS THAN MAXVALUE);  #分成两个文件,用数字划分   

 

create table test6(name varchar(5),age int(3),login_time dateTime) ENGINE=InnoDb

DEFAULT CHARSET=utf8 PARTITION BY RANGE(YEAR(login_time)) (PARTITION p0 VALUES LESS THAN (2018),PARTITION p1 VALUES LESS THAN (2019)

,PARTITION p2 VALUES LESS THAN (2020)

,PARTITION p3 VALUES LESS THAN MAXVALUE);  #分成两个文件    也可以用 时间,dateTime YEAR(login_time)

 

日志数据进行备份的时候 

在mysql v5.7版本后,加入了一个分区交换的概念

  • 表结构要相同

  • 归档的表不能是分区表

  • 归档表不能有外键约束

  • ARCHIVE

create table test5_2016(name varchar(5),age int(3),login_time dateTime) ENGINE=InnoDb

DEFAULT CHARSET=utf8 #归档表

 

ALTER TABLE test5 exchange PARITITON p0 WITH TABLE test5_2016; #将数据备份到归档表中

ALTER TABLE test5_2016 ENGINE=ARCHIVE; #归档,文件会变成极小

 

删除分区文件

ALTER TABLE test5 DROP PARITITON p0; #删除分区文件

 

增加分区文件

ALTER TABLE test5 ADD PARITITON(PARTITION p4 VALUES LESS THAN (2020); #增加分区文件

 

 

问题1:如果一个表不是分区表同时已经有数据,能不能变成分区表?可以,如下:

 

不是分区表变成分区表

ALTER TABLE test5 PARITITON BY RANGE(YEAR(login_time))(PARTITION p4 VALUES LESS THAN (2020)); #增加分区文件,重排数据,但数据量大的情况下I/O消耗很大,这种数据量大的表,要按照修改表结构的方式来进行分区表操作

  • 建立新结构相同的分区表

  • 数据导入

  • 表名切换

 

问题2:既然把表分开了,那我们分区表最大有多少个:1024 

 

分区表的限制和注意事项

  • 如果表里有主键必须包含分区表的分区键

  • 很多时候,使用分区表就不要使用主键了 ,建立主键后可能会影响性能

  • 不要建立过多的分区

  • 分区表不支持外键

  • 分区规则必须要提前设立好,否则修改很麻烦

  • 分区表设定时间单位建议以年为单位

 

日志表的特征

  • 记录非常的多,非常的大

  • 明显的时间区间特征

  • 查询频次低,就近时间点查询频次高

  • 需要定期归档转储 

在这样的表结构下分区表就是我们的最佳实践。

 

作业:测试分区表的特性,上百万数据并发测试

详细笔记可见我的笔记 :https://app.yinxiang.com/shard/s66/nl/16944865/cc8f3c15-fb96-4351-9ae6-52efe7750977

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值