MySQL表分区

MySQL分区详解
本文介绍了MySQL分区的优势、支持的存储引擎及各种分区类型,包括RANGE、LIST、HASH、KEY等,并详细阐述了每种类型的使用场景及注意事项。

mysql分区优点:

  • 和单个磁盘或文件系统分区相比,可以存储更多数据
  • 优化查询
  • 对于过期或不需要保存的数据,通过删除与数据有关的分区来提高效率
  • 跨多个磁盘分散数据查询,以获得更大的查询吞吐量

mysql支持的存储引擎:

  • MyISAM, InnoDB, Memory

同一个分区表的所有分区必须使用同一个存储引擎,但是可以在同一个mysql服务器中,甚至是同一个数据库中,对于不同的分区表使用不同存储引擎。

分区类型:

  • range分区:基于一个给定的连续区间范围,把数据分配到不同的分区
  • list分区:类似于range分区,但list分区基于枚举出的所有的值列表进行分区
  • hash分区:基于给定的分区个数把数据分配到不同的分区
  • key分区:类似于hash分区

无论哪种分区类型,不能使用主键/唯一键字段之外的其他字段分区,即要么分区表上没有主键/唯一键,要么分区表的主键/唯一键都必须包含分区键。
例如:

create table emp(
id int not null,
ename varchar(30),
hired date not null default '1970-01-01',
separated date not null default '9999-12-31',
job varchar(30) not null,
primary key (id)
store_id int not null)
partition by range(store_id)(
partition p0 values less than(10),
partition p1 values less than(20),
partition p2 values less than (30));

这个emp表存在主键,而分区键不是主键,则出现错误,把primary key(id)去掉就可以了。

RANGE分区

create table emp(
id int not null,
ename varchar(30),
hired date not null default '1970-01-01',
separated date not null default '9999-12-31',
job varchar(30) not null,
store_id int not null)
partition by range(store_id)(
partition p0 values less than(10),
partition p1 values less than(20),
partition p2 values less than (30));

如果以日期作为range分区:

create table emp(
id int not null,
ename varchar(30),
hired date not null default '1970-01-01',
separated date not null default '9999-12-31',
job varchar(30) not null,
store_id int not null)
partition by range(YEAR(separated))(
partition p0 values less than(1996),
partition p1 values less than(2001),
partition p2 values less than (2006);

但是这样查询如果不是有函数转换,就无法利用range分区特性提高查询性能,不过range column分区支持非整数分区:

create table emp(
id int not null,
ename varchar(30),
hired date not null default '1970-01-01',
separated date not null default '9999-12-31',
job varchar(30) not null,
store_id int not null)
partition by range COLUMNS(separated)(
partition p0 values less than('1996-01-01'),
partition p1 values less than('2001-01-01'),
partition p2 values less than ('2006-01-01'));

这样创建日期分区就不需要通过函数进行转换了

LIST分区

list分区通过使用partition by list(expr)来实现,expr是某列值或一个基于某列值返回的一个整数值的表达式,与range分区不同,list分区不必声明任何特定的顺序。list分区不存在类似VALUES LESS THAN MAVALUE这样的定义方式。LIST分区和RANGE分区一样,在mysql5.5之前只支持整数分区从而导致额外的函数计算得到整数,不过在5.5之后引入了COLUMNS分区解决了它们只支持整数分区的问题。

COLUMNS分区

COLUMNS分区可细分为RANGE COLUMNS分区和LIST COLUMNS分区,它们都支持整数、日期时间、字符串三大数据类型。

  • 所有整数类型:tinyint, smallint, mediumint, int和bigint,其他数值类型都不支持
  • 日期时间类型:date和datetime
  • 字符类型:char,varchar,binary和varbinary;不支持text和blob类型。

HASH分区

mysql支持两种HASH分区:常规HASH分区和线性HASH分区。创建HASH分区表时,使用PARTITION BY HASH(expr) PARTITIONS num子句,其中,expr是某列值或一个基于某列值返回一个整数值的表达式,num为一个非负的整数,表示分割成分区的数量。
例:

CREATE TABLE emp_hash(
id INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY HASH (store_id) PARTITIONS 4;

线性HASH分区与常规分区的唯一区别就是在PARTITION BY后加上LINEAR.
线性HASH分区的优缺点:在分区维护(增加,删除,合并,拆分)时,mysql能够处理更加迅速;缺点是与常规HASH分区相比,线性HASH分区之间的数据不太均衡。

KEY分区

KEY分区和HASH分区类似,同样可以用PARTITION BY KEY(expr) PARTITIONS num来构建一个key分区表,expr是零个或多个字段名的列表
与HASH分区比较:

  • HASH分区允许用户使用自定义的表达式,而KEY分区不允许,只能使用mysql服务器提供的HASH函数
  • key分区支持除了BLOB和text以外的其他类型作为分区键
  • 创建key分区表时可以不指定分区键,默认会选择主键作为分区键;在没有主键的情况下会选择非空唯一键作为分区键;在没有主键和非空唯一键时,就不能指定分区键了。

mysql分区对NULL值的处理

MYSQL不禁止在分区键值上使用NULL,在RANGE分区中,NULL值会被当做最小值来处理;LIST分区中,NULL值必须出现在枚举列表中,否则不被接受;HASH/KEY分区中,NULL值会被当做零值来处理。

### MySQL 表分区的使用指南与示例 #### 基本概念 MySQL 分区是一种数据库优化技术,允许将一个大表或索引分割成多个较小的部分,这些部分被称为分区。通过这种方式,可以显著提升查询性能、简化维护过程以及增强数据管理效率[^1]。 #### 工作原理 在 MySQL 中,可以通过定义不同的分区策略来实现表分区。常见的分区类型包括 RANGE、LIST、HASH 和 KEY 等。每种类型的适用场景不同,合理选择分区键和分区策略对于最大化性能至关重要[^2]。 #### 创建分区表的语法 以下是几种常见分区方式的具体语法: ##### 1. **RANGE 分区** 适用于按某个字段范围划分数据的情况。 ```sql CREATE TABLE sales ( id INT NOT NULL, sale_date DATE NOT NULL, amount DECIMAL(10, 2) ) PARTITION BY RANGE (YEAR(sale_date)) ( PARTITION p0 VALUES LESS THAN (2020), PARTITION p1 VALUES LESS THAN (2021), PARTITION p2 VALUES LESS THAN (2022), PARTITION p3 VALUES LESS THAN MAXVALUE ); ``` ##### 2. **LIST 分区** 用于基于离散值集合进行分区。 ```sql CREATE TABLE employees ( emp_id INT NOT NULL, department VARCHAR(20) NOT NULL ) PARTITION BY LIST (department) ( PARTITION p_northwest VALUES IN ('North', 'West'), PARTITION p_southeast VALUES IN ('South', 'East') ); ``` ##### 3. **HASH 分区** 适合均匀分布数据的场景。 ```sql CREATE TABLE logs ( log_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) PARTITION BY HASH(YEAR(created_at)) PARTITIONS 4; ``` ##### 4. **KEY 分区** 类似于 HASH 分区,但由存储引擎自动计算哈希值。 ```sql CREATE TABLE users ( user_id INT NOT NULL, username VARCHAR(50) ) PARTITION BY KEY(user_id) PARTITIONS 8; ``` #### 查看分区信息 要查看已创建的分区及其元数据,可利用 `information_schema.PARTITIONS` 表中的信息。 ```sql SELECT PARTITION_NAME AS 分区名称, PARTITION_METHOD AS 分区方法, TABLE_ROWS AS 数据行数, PARTITION_DESCRIPTION AS 描述 FROM information_schema.PARTITIONS WHERE table_name = 'sales'; ``` 如果涉及子分区,则需替换为 `SUBPARTITION_*` 字段以获取详细信息[^4]。 #### 维护分区 随着业务发展,可能需要动态调整分区结构。例如新增分区: ```sql ALTER TABLE sales ADD PARTITION ( PARTITION p_new VALUES LESS THAN (2023) ); ``` 或者删除不再使用的旧分区: ```sql ALTER TABLE sales DROP PARTITION p_old; ``` #### 注意事项 - 提前规划好分区方案非常重要,尤其是在初始化阶段就应考虑未来扩展性[^3]。 - 不同版本间可能存在兼容性差异,请参照官方文档确认支持的功能列表[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值