一般在数据库设计中,要谨慎的使用分区表。

原因:1、分区表在物理上表现为多个文件,在逻辑上表现为一个表。

原因:2、谨慎的使用分区键,跨分区查询效率可能更低

建议采用物理分表的方式管理大数据。

但在特定的数据库模型中,分区表的表现是非常不错的。

如何使用Mysql服务器分区表

1.首先确认MySQL服务器是 否支持分区表

show plugins

查看插件

如果出现partition证明是支持的。

sql语句

建标语句之比正常的语句多出来那么点。

物理文件对比

对比图

Mysql分区类型一、按HASH分区

特点:根据MOD(分区建,分区数)的值把数据行 存储到表的不同分区中。数据可以平均的分布在各个分区中。HASH分区的建值必须是一个INT类型的值,或是通过函数可以转为INT类型。

如:直接用主键直接做键值分区、如上上图。

如:用非INT型数据可用MYSQL函数转为INT型。

 create table `customer_login_log`(
`customer_id` INT(10) UNSIGNED NOT NULL,
`login_time` TIMESTAMP NOT NULL,
`login_ip` INT(10) UNSIGNED NOT NULL,
`login_type` TINYINT(4) NOT NULL
 )ENGINE=INNODB
 PARTITION BY HASH(UNIX_TIMESTAMP(login_time))
 PARTITIONS 4;

可以建立哈希分区可以转INT型的函数列表

图

Mysql分区类型二、案范围分区(RANGE)

RANGE分区特点:1、根据分区键值得范围把数据行存储到表的不同分区中。2、多个分区的范围要连续,但是不能重叠。3、默认情况下使用VALUES LESS THAN属性,既每个分区不包括指定的那个值

建表语句

 create table `customer_login_log`(
`customer_id` INT(10) UNSIGNED NOT NULL,
`login_time` TIMESTAMP NOT NULL,
`login_ip` INT(10) UNSIGNED NOT NULL,
`login_type` TINYINT(4) NOT NULL
 )ENGINE=INNODB
 PARTITION BY RANGE (customer_id)(
 PARTITION p0 VALUES LESS THAN (1000),
 PARTITION p1 VALUES LESS THAN (2000),
 PARTITION p2 VALUES LESS THAN (3000),
 PARTITION p3 VALUES LESS THAN MAXVALUE
);

rangge分区

RANGE分区的使用场景

1、分区键为日期或时间类型,2、适合定期按分区范围清理历史数据。

注意:所有查询中都应该包过分区的键,避免跨分区查询

MYSQL分区类型三、LIST分区

LIST分区的特点:1、按分区键取值得列表进行分区。2、同范围分区一样,各分区的列表值不能重复。3、每一行数据必须能找到对应的分区列表,否则数据插入失败

 create table `customer_login_log`(
`customer_id` INT(10) UNSIGNED NOT NULL,
`login_time` TIMESTAMP NOT NULL,
`login_ip` INT(10) UNSIGNED NOT NULL,
`login_type` TINYINT(4) NOT NULL
 )ENGINE=INNODB
 PARTITION BY LIST (login_type)(
 PARTITION p0 VALUES in (1,3,5,7,9),
 PARTITION p1 VALUES in (2,4,6,8)
);

如果这时候插入login_type=10的数据那么,则会报错。

最适用登录日志表等

适用RANGE分区、以年份做条件、以login_time作为分区键

 create table `customer_login_log`(
`customer_id` INT(10) UNSIGNED NOT NULL,
`login_time` DATETIME NOT NULL,
`login_ip` INT(10) UNSIGNED NOT NULL,
`login_type` TINYINT(4) NOT NULL
 )ENGINE=INNODB
 PARTITION BY RANGE (YEAR(login_time))(
 PARTITION p0 VALUES LESS THAN (2018),
 PARTITION p1 VALUES LESS THAN (2019)
);

需要注意的:这里的login_time类型是DATETIME不是TIMESTAMP。如果是TS则会报错。

插入两条数据查看分区信息

SQL语句

select table_name,partition_name,partition_description,table_rows
 from information_schema.`PARTITIONS` 
WHERE table_name='customer_login_log';

图

两条数据2018>2019房子啊P1分区里了,2017同理。

在每年的年底要做好修改并添加分区的计划任务

用alter语句添加分区

ALTER TABLE customer_login_log ADD PARTITION (
PARTITION p3 VALUES LESS THAN(2020));

删除一个分区

ALTER TABLE customer_login_log DROP PARTITION p0;

删除过期数据非常便捷

数据归档(5.7版本)

1、要求Mysql>=5.7。2、结构相同。归档到数据表一定要是非分区表。4.非临时表;不能有外键约束。5、归档引擎要是:archive.

新建个非分区表

 create table `arch_customer_login_log`(
`customer_id` INT(10) UNSIGNED NOT NULL,
`login_time` DATETIME NOT NULL,
`login_ip` INT(10) UNSIGNED NOT NULL,
`login_type` TINYINT(4) NOT NULL
 )ENGINE=INNODB

交换分区语句

ALTER TABLE customer_login_log exchange PARTITION p1
WITH TABLE arch_customer_login_log;

图

注意事项

合理的设计于使用分区表,

对分区表进行查询最好在WHERE从句中包含分区键,之前的表是那login_time做的分区键,

具有主键或唯一索引的表,主键或唯一索引必须是分区键的一部分

Last modification:February 10, 2020
如果觉得我的文章对你有用,请随意赞赏