分区表的简介
概念
分区表就是将一个表或者索引分解为多个更小、更可管理的部分。就访问数据库而言,从逻辑上讲,只有一个表或者一个索引,但是在物理上这个表或者索引可能由多个物理分区组成。每个分区都是一个独立的对象,可以独自处理,也可以作为一个更大对象的一部分处理。MySQL数据库的分区是局部分区,一个分区中既能存放数据又能存放索引。而全局分区是指数据存放在各个分区中,但是所有数据的索引放在一个对象中,但是目前MySQL不支持全局分区。
目的与应用
分区的一个主要目的是将数据按照一个较粗的粒度分在不同的表中。这样做可以将相关的数据存放在一起,另外,如果想一次批量删除整个分区的数据也会变得很方便。下面是分区表常见的应用场景:
- 表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据
- 分区表的数据更容易维护,分区独立优化,检查,修复等
- 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备
- 可以使用分区表来避免某些特殊的瓶颈,例如 InnoDB 的单个索引的互斥访问、ext3 文件系统的 inode 锁竞争等
- 如果需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好。
目前MySQL支持一下几种类型的分区:
- RANGE分区:基于一个给定连续区间边界,得到若干个连续区间范围,按照分区键的落点,把数据分配到不同的分区;
- LIST分区:类似RANGE分区,区别在于LIST分区是基于枚举出(离散)的值列表分区,RANGE是基于给定连续区间范围分区;
- HASH分区:基于用户自定义的表达式的返回值,对其根据分区数来取模,从而进行记录在分区间的分配的模式。这个用户自定义的表达式,就是MySQL希望用户填入的哈希函数;
- KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且使用MySQL 服务器提供的自身的哈希函数。
注意:
- 如果表存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分
- 唯一索引可以是允许NULL值的,并且分区列只要是唯一索引的一个组成部分,不要求需要整个唯一索引列都是分区列
分区类型
RANGE分区
RANGE分区是实战最常用的一种分区类型,行数据基于属于一个给定的连续区间的列值被放入分区。但是要特别注意,如果插入的数据不在指定的分区范围内,就会抛出错误。RANGE分区主要用于日期列的分区,比如交易表啊,销售表,可以根据年月来存放数据。
注意: 如果分区走的唯一索引中date类型的数据,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择。一般将日期转为时间戳分区比较方便。
例如:
create table foo_range (id int not null auto_increment,created DATETIME,primary key (id, created)) engine = innodb partition by range (TO_DAYS(created))(PARTITION foo_1 VALUES LESS THAN (TO_DAYS('2016-10-18')),PARTITION foo_2 VALUES LESS THAN (TO_DAYS('2017-01-01')));insert into `foo_range` (`id`, `created`) values (1, '2016-10-17'),(2, '2016-10-20'),(3, '2016-1-25');
LIST分区
类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。例如:
create table foo_list
(empno varchar(20) not null ,
empname varchar(20),
deptno int,
birthdate date not null,
salary int
)
partition by list(deptno)
(
partition p1 values in (10),
partition p2 values in (20),
partition p3 values in (30)
);
HASH分区
基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。HASH分区主要用来确保数据在预先确定数目的分区中平均分布。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中。在HASH分区中,MySQL 自动完成这些工作,所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。例如:
create table foo_hash
(empno varchar(20) not null ,
empname varchar(20),
deptno int,
birthdate date not null,
salary int
)
partition by hash(year(birthdate))
partitions 4;
KEY分区
类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。
create table foo_key
(empno varchar(20) not null ,
empname varchar(20),
deptno int,
birthdate date not null,
salary int
)
partition by key(birthdate)
partitions 4;
注意: 分区不一定能带来查询性能上的提升,只要合适情况下合理的分区才能带来性能上的提升。
OLTP和OLAP
数据库的应用一般分为两类,一类是OLTP(在线事务处理),比如:Blog、电子商务、网络游戏、转账金融系统等等;另一类就是OLAP(在线分析处理),比如:数据仓库、数据集市。



