MySQL表分区注意事项

1、分区列索引约束
若表有primary key或unique key,则分区表的分区列必须包含在primary key或unique key列表里,这是为了确保主键的效率,否则同一主键区的东西一个在A分区,一个在B分区,显然会比较麻烦。

2、各分区类型条件
range 每个分区包含那些分区表达式的值位于一个给定的连续区间内的行。这些区间要连续且不能相互重叠

list只支持整形字段或返回整形数的表达式,每个分区列表里的值列表必须整数

hash类型只支持整形字段或返回整形数的表达式

key类型只支持列名形式(可一个或多个列名),不支持表达式

3、分区可用函数
ABS()

CEILING() (see CEILING() and FLOOR(), immediately following this list)

DAY()

DAYOFMONTH()

DAYOFWEEK()

DAYOFYEAR()

DATEDIFF()

EXTRACT()

FLOOR() (see CEILING() and FLOOR(), immediately following this list)

HOUR()

MICROSECOND()

MINUTE()

MOD()

MONTH()

QUARTER()

SECOND()

TIME_TO_SEC()

TO_DAYS()

WEEKDAY()

YEAR()

YEARWEEK()

注意:

因为分区函数不包括FROM_UNIXTIME函数,所以用时间戳转时间来分区就无法实现了,只能用date或者datetime来分区

例如按年我们可以用:

PARTITION BY RANGE (YEAR(date))

按月:

PARTITION BY RANGE(date div 100)   

#div 会把日期变成整数,例如:2014-12-01 -> 20141201、100就是从后面去掉两位,最后结果是201412

一个订单做分区的例子:

CREATE TABLE `order` (
  `order_id` bigint(19) NOT NULL DEFAULT '0' COMMENT '订单ID:年月日时分秒12位+7位随机数',
  `date` date NOT NULL DEFAULT '0000-00-00' COMMENT '订单日期',
  `amount` int(11) DEFAULT NULL COMMENT '支付金额,单位分',
  `status` tinyint(1) DEFAULT '0' COMMENT '0:等待支付 1:支付成功 2:支付失败 3:验证失败',
  `addtime` int(10) DEFAULT NULL COMMENT '订单添加时间',
  PRIMARY KEY (`order_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
因为我们没法用时间戳来做按时间分区,所以添加了一个date字段,这个字段和order_id一起作为主键,我们知道分区的列一定要放到主键里面去的。下面我们用date计算成年月组合来分区

ALTER TABLE order PARTITION BY RANGE( date DIV 100)
(
    PARTITION p_2014_06 VALUES LESS THAN (201407),
    PARTITION p_2014_07 VALUES LESS THAN (201408),
    PARTITION p_2014_08 VALUES LESS THAN (201409),
    PARTITION p_2014_09 VALUES LESS THAN (201410),
    PARTITION p_2014_10 VALUES LESS THAN (201411),
    PARTITION p_catch_all VALUES LESS THAN MAXVALUE
);
以上 LESS THAN MAXVALUE 设置了最后一个分区p_catch_all,所以不能用add的方式来添加分区了,以下语句不可用:

ALTER TABLE order ADD PARTITION (PARTITION p_2014_11 VALUES LESS THAN (201412));
只能把最后的p_catch_all分区拆分成两个,这样还有一个好处就是在p_catch_all分区的数据不会丢失。数据的合并与拆分用REORGANIZE PARTITION进行。

alter table order reorganize partition p_catch_all into
(
    partition p_2014_11 values less than (201412),
    partition p_catch_all values less than maxvalue
);
合并分区:

alter table order reorganize partition p_2014_10,p_2014_11,p_catch_all into
(
    partition p_catch_test values less than MAXVALUE
);
为什么不分到p_catch_all去?因为会报分区以存在。

为什么合并的时候要带上最后一个分区p_catch_all?因为除了最后一个分区,其他重组的分区范围不能改变总范围。

删除分区但是不删除数据:

alter table 表名 remove partitioning
注意:上面语句在5.5可以执行,5.6好像有问题,要先测试一下

分区之后,where条件是一个范围的话分区是不起作用的,如 where date >= '2014-01-01' And date <= '2014-01-31'

一定要用 = 或者 in 条件才行 where date = '2014-01-01' 或者 where date in ('2014-01-01', '2014-01-02', '2014-01-03'...)

时间: 2024-10-22 08:55:07

MySQL表分区注意事项的相关文章

MySQL数据库表分区注意事项总结

1.分区列索引约束 若表有primary key或unique key,则分区表的分区列必须包含在primary key或unique key列表里,这是为了确保主键的效率,否则同一主键区的东西一个在A分区,一个在B分区,显然会比较麻烦. 2.各分区类型条件 range 每个分区包含那些分区表达式的值位于一个给定的连续区间内的行.这些区间要连续且不能相互重叠 list只支持整形字段或返回整形数的表达式,每个分区列表里的值列表必须整数 hash类型只支持整形字段或返回整形数的表达式 key类型只支

mysql 表分区的问题

问题描述 mysql 数据库现在有一批庞大的数据入库,需要根据用户的uid 进行表分区.用户的uid基本上是10位数的随机数,现在有什么好的办法根据uid 来做表分区? 解决方案 hash的分区方式应该是你要找的.参考http://lehsyh.iteye.com/blog/732719解决方案二:楼下说的对,直接把uid取出来进行一次hash即可~!当然,也可以根据其他字段分区了,看你怎么查询了

mysql表分区创建使用学习笔记

表分区的测试使用,主要内容来自于其他博客文章以及mysql5.1的参考手册 mysql测试版本:mysql5.5.28 mysql物理存储文件(有mysql配置的datadir决定存储路径)格式简介 数据库engine为MYISAM   frm表结构文件,myd表数据文件,myi表索引文件. INNODB engine对应的表物理存储文件 " innodb的数据库的物理文件结构为: .frm文件 .ibd文件和.ibdata文件: 这两种文件都是存放innodb数据的文件,之所以用两种文件来存放

教你实现MySQL表数据迁移自动化

一.背景 之前我写过关于SQL Server的数据迁移自动化的文章:SQL Server 数据库迁移偏方,在上篇文章中设计了一张临时表,这个临时表记录搬迁的配置信息,用一个存储过程读取这张表进行数据的迁移,再由一个Job进行迭代调用这个存储过程. 在这次MySQL的实战中,我的数据库已经做了4个分片,分布在不同的4台机器上,每台机器上的数据量有1.7亿(1.7*4=6.8亿),占用空间260G(260*4=1040G),这次迁移的目的就是删除掉一些历史记录,减轻数据库压力,有人说这为什么不使用表

总结MySQL的分区_Mysql

前言      分区是指根据一定的规则将一个大表分解成多个更小的部分,这里的规则一般就是利用分区规则将表进行水平切分:逻辑上没有发生变化但实际上表已经被拆分成了多个物理对象,每个分成被划分成了一个独立的对象.相对于没有分区的当个表而言分区的表有很多的优势包括: 并发统计查询.快速归档删除分区数据.分散存储.查询性能更佳. mysql5.7以后查询语句支持指定分区例如:" SELECT * FROM t PARTITION (p0,p1) WHERE c < 5 "指定分区同样适用

Mysql数据表分区技术PARTITION浅析_Mysql

在这一章节里, 我们来了解下 Mysql 中的分区技术 (RANGE, LIST, HASH)   Mysql 的分区技术与水平分表有点类似, 但是它是在逻辑层进行的水平分表, 对于应用而言它还是一张表, 换句话说: 分区不是实际真正的对一张表进行拆分,分区之后表还是一个表,它是把存储文件进行拆分. 在 Mysql 5.1(后) 有了几种分区类型:   RANGE分区: 基于属于一个给定连续区间的列值, 把多行分配给分区 LIST分区: 类似于按 RANGE 分区, 区别在于 LIST 分区是基

MySQL表的四种分区类型详解

一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区.当然也可根据其他的条件分区. 二.为什么要对表进行分区 为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率. 分区的一些优点包括: 与单个磁盘或文件系统分区相比,可以存储更多的数据. 对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数

MySQL的表分区

一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区.当然也可根据其他的条件分区.   二.为什么要对表进行分区 为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率. 分区的一些优点包括:       1).与单个磁盘或文件系统分区相比,可以存储更多的数据.       2).对于那些已经失去保存意义的数据,通常可以通过删除

MYSQL查看和新增表分区

MYSQL查看和新增表分区 1.查看表分区 SELECT  partition_name part,   partition_expression expr,   partition_description descr,   FROM_DAYS(partition_description) lessthan_sendtime,   table_rows FROM  INFORMATION_SCHEMA.partitions WHERE  TABLE_SCHEMA = SCHEMA()   AND