Mysql分区表


分区不是在引擎层实现的,所以常见的引擎都支持,至少MyISAM和InnoDB是支持的。就访问数据库的程序而言,从逻辑上将,只有一个表或一个索引,但在物理上这个表或者索引可能由数十个物理分区组成。每个分区都是独立的对象,可以单独处理,也可以作为一个更大对象的一部分处理。

MySQL支持水平分区,即按行分区,不支持垂直分区。MySQL数据库的分区是局部分区索引,一个分区既存放数据也存放索引。

可通过如下命令查看当前数据库是否启用了分区功能。

show variables like '%partition%';
或者
show pulgins;

分区类型

RANGE分区:行数据基于一个给定连续范围分区。不好理解,看例子吧。5.5开始支持RANGE COLUMNS分区。

LIST分区:同RANGE,区别在于给定的不是连续范围,是离散的值。5.5开始支持LIST COLUMNS分区。

HASH分区:根据用户自定义的表达式的返回值进行分区,返回值不能是负数。

KEY分区:根据MySQL内部提供的哈希函数进行分区。

COLUMNS分区:5.5开始支持,可以直接使用非整形的数据进行分区,分区根据类型直接比较而得,不需要转换为整形。

无论创建何种类型的分区,如果表中存在主键或唯一索引的列,则分区列必须是主键或唯一索引的一部分。索引列可以是null值。在没有主键和唯一索引的表中可以指定任意列为索引列。

按日期分表(range)

datetime
CREATE TABLE `km_sensor_info_his` (
	`DEVICE_ID` VARCHAR (16) NOT NULL COMMENT '设备编号  temp:温度 humidity:湿度 hzsppm:硫化氢浓度 energy:电量',
  `TYPE` VARCHAR (11) NOT NULL COMMENT '设备类型',
	`TEMP` FLOAT (11, 1) DEFAULT NULL COMMENT '参数名称 temp:温度',
	`HUMIDITY` FLOAT (11, 1) DEFAULT NULL COMMENT '参数名称 humidity:湿度',
	`HZSPPM` FLOAT (11, 2) DEFAULT NULL COMMENT '参数名称 hzsppm:硫化氢浓度 ',
	`MOISTURE` FLOAT (11, 1) DEFAULT NULL COMMENT '参数名称 moisture:水分',
	`ENERGY` FLOAT (11, 0) DEFAULT NULL COMMENT '参数名称 energy:电量',
	`COLLECT_TIME` datetime NOT NULL COMMENT '时间戳',
	`import_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	`PRESSURE` FLOAT (11, 2) DEFAULT NULL COMMENT '气压',
	`CSQ` FLOAT (11, 2) DEFAULT NULL COMMENT '信号强度',
	`device_status` TINYINT (2) DEFAULT NULL COMMENT '设备状态',
	`run_status` TINYINT (2) DEFAULT NULL COMMENT '设备运行状态',
	`protect` TINYINT (2) DEFAULT NULL COMMENT '保护状态',
	`micro_range_hzsppm` FLOAT (11, 2) DEFAULT NULL COMMENT '小量程',
	`macro_range_hzsppm` FLOAT (11, 1) DEFAULT NULL COMMENT '大量程',
	`exception_status` TINYINT (1) DEFAULT '1' COMMENT '是否异常,1为无异常,2为异常',
	`sw_ver` VARCHAR (30) NOT NULL COMMENT '软件版本',
	PRIMARY KEY (`DEVICE_ID`,`TYPE`, `COLLECT_TIME`) USING BTREE
) ENGINE = INNODB DEFAULT CHARSET = utf8 
PARTITION BY RANGE(TO_DAYS(COLLECT_TIME))
(
PARTITION part1 VALUES LESS THAN ( TO_DAYS('20190101') ),
PARTITION part2 VALUES LESS THAN ( TO_DAYS('20190701') ),
PARTITION part3 VALUES LESS THAN ( TO_DAYS('20200101') )
);

新增分区

ALTER TABLE `km_sensor_info_his_f` ADD PARTITION (
	PARTITION p4
	VALUES
		LESS THAN (TO_DAYS(20200701)) ENGINE = INNODB
);

分区成功
在这里插入图片描述
查看执行结果

EXPLAIN
SELECT *
FROM
	km_sensor_info_his_f
WHERE
	COLLECT_TIME BETWEEN '2019-07-23 15:13:54.0' AND '2019-08-24 15:13:54.0';

在这里插入图片描述
可以看到分区成功,但mysql默认扫描第一个分区,所以可以将第一个分区置空,提升速率

没有分区的表
在这里插入图片描述

查看分区信息

SELECT
	partition_name part,
	partition_expression expr,
	partition_description descr,
	table_rows
FROM
	INFORMATION_SCHEMA. PARTITIONS
WHERE
	TABLE_SCHEMA = SCHEMA ()
AND TABLE_NAME = 'km_sensor_info_his_f';

timestamp
CREATE TABLE `km_sensor_info_his` (
	`DEVICE_ID` VARCHAR (16) NOT NULL ,
	`TYPE` VARCHAR (11)  NOT NULL,
	`COLLECT_TIME` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`DEVICE_ID`, `TYPE`,`COLLECT_TIME`) USING BTREE
) ENGINE = INNODB  DEFAULT CHARSET=utf8 
PARTITION BY RANGE (
	UNIX_TIMESTAMP(COLLECT_TIME)
)(
	PARTITION part_1 VALUES LESS THAN (1546272000) ENGINE = INNODB,
	PARTITION part_2 VALUES LESS THAN (1559318400) ENGINE = INNODB,
	PARTITION part_3 VALUES LESS THAN (1577808000) ENGINE = INNODB
);

List分区

LIST分区和RANGE分区非常相似,只是LIST分区的值是离散的。与RANGE分区的 VALUES LESS THAN 不同,LIST分区使用 VALUES IN,所以每个分区的值是离散的,只能是定义的值。如

create table t(
a int(11), b int(11)
)engine=innodb partition by list(b)(
partition pe values in(1,3,5,7,9),partition p1 values in(2,4,6,8,10)
);

如果插入的值不在分区定义中,会报错

insert into t select 11;
[Err] 1526 - Table has no partition for value 11

参考链接:
Mysql分区表
Mysql基于时间字段进行分区

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值