一、什么是表分区?
表分区就是将一个大的数据库表进行拆分成很多个独立的逻辑表,其内部是被拆分成多个物理的子表,但是对外部使用时还是体现为一个表。这个跟分表相似但又不同,分表也是将一张大表拆分成多个小表,但是对于外部使用时分表就需要指定使用哪张对应的小表。
二、表分区的基本类型
1. Range分区
Range分区也叫范围分区,将某个列按照一定的范围进行分区,该类型只适用于结果为数字,也就是说要么列为数字类型,要么可以通过函数将列的值转成数字类型。
Range分区案例:
create table test_partition(
name VARCHAR(10) not null DEFAULT '' ,
age int(10) not null DEFAULT 0,
sex TINYINT(2) not null DEFAULT 0
) ENGINE=INNODB CHARSET=utf8
PARTITION by RANGE(age)
(
PARTITION p1 values less than (10),
PARTITION p2 values less than (20),
PARTITION p3 values less than (30),
PARTITION p4 values less than (MAXVALUE)
);
创建一张 test_partition表,按照年龄进行分区,分为4个区,分别是0-10为p1区,10-20为p2区,20-30为p3区30以上为p4区。
生成文件如下图:
2. List分区
List分区和Range分类似,List分区的区别在于它是按照某个列值的集合进行分区。
List分区案例:
create table test_partition2(
title VARCHAR(10) not null DEFAULT '' ,
type int(10) not null DEFAULT 0,
description varchar(255)
) ENGINE=INNODB CHARSET=utf8
PARTITION by list(type)
(
PARTITION p1 values in (1,2,3),
PARTITION p2 values in (4,5,6)
);
如上代码可以看出,我们是按照type字段进行分区,type为1、2、3的分为p1区,type为4、5、6的分为p2区。
生成文件如下图:
3. hash分区
hash 分区有两种:常规hash 和线性hash分区。
3.1 常规hash分区
常规hash分区是在分区的列上根据所需要分区的数量进行取模运算得出的余数就是分区的位置,因此常规hash分区也需要列值为整数或者是通过计算得出值位置整数的列。
例如:如果分为为3个区则为P0,P1,P2 。
当数值为2时,2/3余2, 那么则为P2分区;
当数值为10时,10/3余1, 那么则为P1分区;
当数值为12时,12/3余0, 那么则为P0分区;
create table test_partition(
name VARCHAR(10) not null DEFAULT '' ,
age int(10) not null DEFAULT 0,
sex TINYINT(2) not null DEFAULT 0
) ENGINE=INNODB CHARSET=utf8
PARTITION by hash(age) -- 分区列为age
PARTITIONS 3; -- 分区数量为3
3.2 线性hash分区
线性hash是对分区字段进行二次方运算,根据运算结果分区。线性hash分区也需要列值为整数或者是通过计算得出值位置整数的列。
线性分区的计算规则:
set @p_num=3; --分区数量
set @value=34; -- 列字段值
set @p = @value & (power(2, ceil(log(2, @p_num)))-1); -- 计算出分区的位置
create table test_partition(
name VARCHAR(10) not null DEFAULT '' ,
age int(10) not null DEFAULT 0,
sex TINYINT(2) not null DEFAULT 0
) ENGINE=INNODB CHARSET=utf8
PARTITION by linear hash(age) -- 分区列为age
PARTITIONS 3; -- 分区数量为3
三、表分区的限制
- 一个表最多只能有1024个分区。
- 如果分区字段中有主键或者是唯一索引的列,那么所有的主键列和唯一索引列都必须被包含。
- 分区表无法使用外键约束。
- 进行分区的列为null时分区过滤则无效,所以分区的列不能为null。
- 定义的索引列和分区列不匹配时,查询时则无法进行分区过滤。