MySQL分区表语法解读

 更新时间:2025年02月18日 10:45:33   作者:Why9310  
MySQL分区表主要用于提高查询效率,通过将数据分割成更小的部分进行管理,文章详细介绍了如何创建、查询、修改和存储分区表,包括创建复合主键、按年份和月份分区、删除分区、查询分区数据以及利用存储过程批量转换非分区表为分区表等方法

MySQL分区表语法

1.创建分区表

分区键需要和主键设置为复合主键,分区表不可直接转换成非分区表,需要重新建非分区表并导入数据

  • 按年份
CREATE TABLE partitioned_table_year (
    id INT,
    content VARCHAR(50),
    created_time DATETIME,
                PRIMARY KEY (id,created_time)
) PARTITION BY RANGE(YEAR(created_time)) ( 
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION p2025 VALUES LESS THAN (2026),
    PARTITION p2026 VALUES LESS THAN (2027)
);
  • 按月份
CREATE TABLE partitioned_table_month (
    id INT,
    content VARCHAR(50),
    created_time DATETIME,
                PRIMARY KEY (id,created_time)
) PARTITION BY RANGE  COLUMNS(created_time)  (  
    PARTITION p202410 VALUES LESS THAN ('2024-11-01'),
    PARTITION p202411 VALUES LESS THAN ('2024-12-01'), 
    PARTITION p202412 VALUES LESS THAN ('2025-01-01')
);
  • 修改表结构,增加分区
ALTER TABLE `partitioned_table_month` MODIFY COLUMN `created_time` datetime(0) NOT NULL ,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`, `created_time`) USING BTREE;

ALTER TABLE partitioned_table_month PARTITION BY RANGE COLUMNS(created_time) (  
    PARTITION p202410 VALUES LESS THAN ('2024-11-01'),
    PARTITION p202411 VALUES LESS THAN ('2024-12-01'), 
    PARTITION p202412 VALUES LESS THAN ('2025-01-01')
                 );
  • 删除分区,注意:删除分区的时候会同时删除数据
ALTER TABLE partitioned_table_month DROP PARTITION p202407,p202408;

2.查询

  • 查看表分区
SELECT  
    TABLE_NAME,
    PARTITION_NAME, 
    PARTITION_METHOD, 
    PARTITION_EXPRESSION, 
    PARTITION_DESCRIPTION,
    TABLE_ROWS,
    AVG_ROW_LENGTH,
    DATA_LENGTH,
    INDEX_LENGTH 
FROM 
    information_schema.PARTITIONS
WHERE 
    TABLE_SCHEMA = 'xxx' and TABLE_NAME = 'partitioned_table_month';  
  • 查看分区数据
select * from partitioned_table PARTITION (p2024,p2025)

3.利用存储过程批量修改非分区表为分区表

  • 创建联合主键存储过程,先设置联合主键字段非空,再删除原id去掉主键,再设置联合主键
DELIMITER $$
DROP PROCEDURE IF EXISTS auto_create_pk$$
CREATE PROCEDURE `auto_create_pk`(IN `table_name` varchar(64),IN `column_name` varchar(64),IN `column_comment` varchar(64))
BEGIN
	  SET @sql = CONCAT("ALTER TABLE `",table_name,"` MODIFY COLUMN `",column_name,"` datetime  NOT NULL COMMENT '",column_comment,"',
		DROP PRIMARY KEY,
		ADD PRIMARY KEY ( `id`, `",column_name,"` ) USING BTREE;");
		PREPARE stmt FROM @sql;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;
END$$ 
DELIMITER ;
  • 创建按年自动分区存储过程
DELIMITER $$
DROP PROCEDURE IF EXISTS auto_create_partition_year$$
CREATE PROCEDURE `auto_create_partition_year`(IN `table_name` varchar(64),IN `column_name` varchar(64))
BEGIN
		DECLARE partitioned LONGTEXT;
		DECLARE n INT;
		set n = 2025;
		set partitioned = '';
		WHILE n <= 2027 DO
			SET partitioned = CONCAT(partitioned,",PARTITION p",n," VALUES LESS THAN (",n+1,")");
			SET n = n + 1;
			END WHILE;  
		SET @sql = CONCAT ("ALTER TABLE ",table_name,"  PARTITION BY RANGE(YEAR(",column_name,")) (",SUBSTR(partitioned,2,LENGTH(partitioned)),");") ; 
		PREPARE stmt FROM @sql;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;
END$$ 
DELIMITER ;
  • 创建按月自动分区存储过程
DELIMITER $$
DROP PROCEDURE IF EXISTS auto_create_partition_month$$
CREATE PROCEDURE `auto_create_partition_month`(IN `table_name` varchar(64),IN `column_name` varchar(64))
BEGIN
		DECLARE partitioned LONGTEXT;
		DECLARE n INT;
		DECLARE m INT;
		set n = 2015;
		set partitioned = '';
		WHILE n <= 2030 DO
		set m = 1;
			WHILE m < 12 DO
				SET partitioned = CONCAT(partitioned,",PARTITION p",n,LPAD(m,2,0)," VALUES LESS THAN ('",n,"-",LPAD(m+1,2,0),"-01')");
				SET m = m + 1;
			END WHILE;  
			IF m = 12 THEN 
				SET partitioned = CONCAT(partitioned,",PARTITION p",n,"12 VALUES LESS THAN ('",n+1,"-01-01')");
			END IF;
			SET n = n + 1;
			END WHILE;   
		SET @sql = CONCAT ("ALTER TABLE ",table_name,"  PARTITION BY RANGE COLUMNS(",column_name,")  (",SUBSTR(partitioned,2,LENGTH(partitioned)),");") ; 
		PREPARE stmt FROM @sql;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;
END$$ 
DELIMITER ;
-- 查询存储过程
show procedure status like 'auto_create_partition%';
-- 执行联合主键
CALL auto_create_pk('table_a','a_time','时间'); 
-- 执行按年自动分区
CALL auto_create_partition_year('table_b','b_time'); 
-- 执行按月自动分区
CALL auto_create_partition_month('table_c','c_time'); 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL 不等于的三种使用及区别

    MySQL 不等于的三种使用及区别

    MySQL中常用到判断符号,而不等于是比较常用的符号,不等于主要是三种,本文主要介绍了三种的使用及区别,感兴趣的同学可以了解一下
    2021-06-06
  • 浅谈mysql中concat函数,mysql在字段前/后增加字符串

    浅谈mysql中concat函数,mysql在字段前/后增加字符串

    下面小编就为大家带来一篇浅谈mysql中concat函数,mysql在字段前/后增加字符串。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • MySQL对数据库和表进行DDL命令的操作代码

    MySQL对数据库和表进行DDL命令的操作代码

    DDL(Data Definition Language),是数据定义语言的缩写,它是SQL(Structured Query Language)语言的一个子集,用于定义或修改数据库的结构,本文给大家介绍了MySQL对数据库和表进行DDL命令的操作,需要的朋友可以参考下
    2024-07-07
  • Mysql8创建用户以及赋权操作过程

    Mysql8创建用户以及赋权操作过程

    文章详细介绍了MySQL 8中创建用户、赋权及权限管理的操作步骤,包括创建不限制IP的用户、赋权数据库所有表、使用WITH GRANT OPTION传递权限、刷新权限、撤销权限、删除用户等,同时强调了权限修改后需刷新及注意权限继承关系
    2025-07-07
  • Navicat连接不上MySQL的问题解决

    Navicat连接不上MySQL的问题解决

    最近遇到了一件非常棘手的问题,用Navicat远程连接数据库居然连接不到,真是头都大了,下面这篇文章主要给大家介绍了关于Navicat连接不上MySQL的问题解决,需要的朋友可以参考下
    2023-02-02
  • mysql 5.7.21 winx64绿色版安装配置方法图文教程

    mysql 5.7.21 winx64绿色版安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 5.7.21 winx64绿色版安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • mysql记录耗时的sql实例详解

    mysql记录耗时的sql实例详解

    这篇文章主要介绍了mysql记录耗时的sql实例详解的相关资料,这里提供实现方法,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08
  • mysql报错ERROR 1396 (HY000): Operation ALTER USER failed for root@localhost解决方式

    mysql报错ERROR 1396 (HY000): Operation ALT

    这篇文章主要给大家介绍了关于mysql报错ERROR 1396 (HY000): Operation ALTER USER failed for root@localhost的解决方式,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-05-05
  • MySQL中正则表达式用法示例详解

    MySQL中正则表达式用法示例详解

    MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配,这篇文章主要介绍了MySQL中正则表达式用法,需要的朋友可以参考下
    2025-06-06
  • mysql请求阻塞问题解析

    mysql请求阻塞问题解析

    这篇文章主要介绍了mysql请求阻塞问题解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-10-10

最新评论