外观
范围分区
范围分区应该是连续且不重叠的,使用 value less than 运算符来定义。
创建表,并通过 partition by range 子句将表按 salary 列进行分区:
mysql
create table employees
(
empno varchar(20) not null,
empname varchar(20),
deptno int,
birthdate date,
salary int
)
partition by range(salary) (
partition p0 values less than (5000),
partition p1 values less than (10000),
partition p2 values less than (15000),
partition p3 values less than (20000),
partition p4 values less than maxvalue
);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MAXVALUE
RANGE 分区语法里,MAXVALUE 代表无穷大,用来作为最后一个分区的上限,接收所有超出前面分区范围的数据,防止数据写入时报分区不存在错误。
当员工工资增长到 25000、30000 或更多时,可以使用 alter table 语句为 20000~25000 的工资范围添加新分区。
针对上面这个员工表,我们也可以根据员工的出生日期(birthdate)进行分区,把同一年出生的员工信息存储在同一个分区中,像下面这样(以 year(birthdate) 作为分区依据)。
mysql
create table employees
(
empno varchar(20) not null,
empname varchar(20),
deptno int,
birthdate date,
salary int
)
partition by range(year(birthdate) (
partition p2018 values less than (2018),
partition p2019 values less than (2019),
partition p2020 values less than (2020),
partition p2021 values less than (2021),
partition pmax values less than maxvalue
);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
查询每个分区中分配的数据量
mysql
select partition_name as "", table_rows as ""
from information_schema.partitions
where table_name="employees";1
2
3
2
3
得到结果格式如下:
| / | / |
|---|---|
| p0 | 0 |
| p1 | 1 |
| p2 | 1 |
| p3 | 1 |
| p4 | 0 |
业务通用落地建议
流水日志类表(强烈建议 RANGE 按月分区)
sql
-- 按创建时间按月分区示例
CREATE TABLE operation_log (
id BIGINT,
content VARCHAR(500),
create_time DATETIME
) ENGINE=InnoDB
PARTITION BY RANGE (TO_DAYS(create_time)) (
PARTITION p202601 VALUES LESS THAN (TO_DAYS('2026-02-01')),
PARTITION p202602 VALUES LESS THAN (TO_DAYS('2026-03-01'))
);1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
优势:按月归档,删旧分区秒级完成,查当月数据只扫描单个分区。