数据库表分区

1、什么是表分区

      表分区是将一大表,根据条件分割成若干个小表。mysql5.1开始支持数据表分区了。
如:某用户表的记录超过了800万条,那么就能够根据入库日期将表分区,也能够根据所在地将表分区。固然也可根据其余的条件分区。mysql

2、为何要对表进行分区

       数据库分区是一种物理数据库设计技术。虽然分区技术能够实现不少效果,但其主要目的是为了在特定的SQL操做中减小数据读写的总量以缩减sql语句的响应时间,同时对于应用来讲分区彻底是透明的。算法

为了改善大型表以及具备各类访问模式的表的可伸缩性,可管理性和提升数据库效率。sql

3、分区类型

· RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。 
· LIST分区:相似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。 
· HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数能够包含MySQL 中有效的、产生非负整数值的任何表达式。
· KEY分区:相似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。数据库

4、mysql分区表经常使用操做示例

以部门员工表为例子:express

1)   建立range分区服务器

create table empless

(empno varchar(20) not null ,数据库设计

empname varchar(20),函数

deptno int,优化

birthdate date,

salary int

)

partition by range(salary)

(

partition p1 values less than (1000),

partition p2 values less than (2000),

partition p3 values less than maxvalue

);

2)       建立list分区

create table emp

(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)

);

以部门做为分区依据,每一个部门作一分区。

3)       建立hash分区

HASH分区主要用来确保数据在预先肯定数目的分区中平均分布。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪 个分区中;而在HASH分区中,MySQL 自动完成这些工做,你所要作的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by hash(year(birthdate))

partitions 4;

4)       建立key分区

按照KEY进行分区相似于按照HASH分区,除了HASH分区使用的用户定义的表达式,而KEY分区的哈希函数是由MySQL 服务器提供,服务器使用其本身内部的哈希函数,这些函数是基于与PASSWORD()同样的运算法则。“CREATE TABLE ...PARTITION BY KEY”的语法规则相似于建立一个经过HASH分区的表的规则。它们惟一的区别在于使用的关键字是KEY而不是HASH,而且KEY分区只采用一个或多个 列名的一个列表。

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by key(birthdate)

partitions 4;

5)       建立复合分区

 

range - hash(范围哈希)复合分区

 

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by range(salary)

subpartition by hash(year(birthdate))

subpartitions 3

(

partition p1 values less than (2000),

partition p2 values less than maxvalue

);

range- key复合分区

 

create table emp

(empno varchar(20) not null ,

empname varchar(20),

deptno int,

birthdate date not null,

salary int

)

partition by range(salary)

subpartition by key(birthdate)

subpartitions 3

(

partition p1 values less than (2000),

partition p2 values less than maxvalue

);

list - hash复合分区

CREATE TABLE emp (

empno varchar(20) NOT NULL,

empname varchar(20) ,

deptno int,

birthdate date NOT NULL,

salary int

)

PARTITION BY list (deptno)

subpartition by hash(year(birthdate))

subpartitions 3

(

PARTITION p1 VALUES in  (10),

PARTITION p2 VALUES in  (20)

)

;

list - key 复合分区

 

CREATE TABLE empk (

empno varchar(20) NOT NULL,

empname varchar(20) ,

deptno int,

birthdate date NOT NULL,

salary int

)

PARTITION BY list (deptno)

subpartition by key(birthdate)

subpartitions 3

(

PARTITION p1 VALUES in  (10),

PARTITION p2 VALUES in  (20)

);

6)       分区表的管理操做

删除分区:

alter table emp drop partition p1;

不能够删除hash或者key分区。

一次性删除多个分区,alter table emp drop partition p1,p2;

增长分区:

alter table emp add partition (partition p3 values less than (4000));

alter table empl add partition (partition p3 values in (40));

分解分区:

Reorganizepartition关键字能够对表的部分分区或所有分区进行修改,而且不会丢失数据。分解先后分区的总体范围应该一致。

alter table te

reorganize partition p1 into

(

partition p1 values less than (100),

partition p3 values less than (1000)

); ----不会丢失数据

合并分区:

Merge分区:把2个分区合并为一个。
alter table te

reorganize partition p1,p3 into

(partition p1 values less than (1000));

----不会丢失数据

从新定义hash分区表:

Alter table emp partition by hash(salary)partitions 7;

----不会丢失数据

从新定义range分区表:

Alter table emp partitionbyrange(salary)

(

partition p1 values less than (2000),

partition p2 values less than (4000)

); ----不会丢失数据

删除表的全部分区:

Alter table emp removepartitioning;--不会丢失数据

重建分区:

这和先删除保存在分区中的全部记录,而后从新插入它们,具备一样的效果。它可用于整理分区碎片。

ALTER TABLE emp rebuild partitionp1,p2;

优化分区:

若是从分区中删除了大量的行,或者对一个带有可变长度的行(也就是说,有VARCHAR,BLOB,或TEXT类型的列)做了许多修改,可使用“ALTER TABLE ... OPTIMIZE PARTITION”来收回没有使用的空间,并整理分区数据文件的碎片。

ALTER TABLE emp optimize partition p1,p2;

分析分区:

读取并保存分区的键分布。

ALTER TABLE emp analyze partition p1,p2;

修补分区:

修补被破坏的分区。

ALTER TABLE emp repairpartition p1,p2;

检查分区:

可使用几乎与对非分区表使用CHECK TABLE 相同的方式检查分区。

ALTER TABLE emp CHECK partition p1,p2;

这个命令能够告诉你表emp的分区p1,p2中的数据或索引是否已经被破坏。若是发生了这种状况,使用“ALTER TABLE ... REPAIR PARTITION”来修补该分区。

【mysql分区表的局限性】

1.      在5.1版本中分区表对惟一约束有明确的规定,每个惟一约束必须包含在分区表的分区键(也包括主键约束)。

 

CREATE TABLE emptt (

empno varchar(20) NOT NULL  ,

empname varchar(20),

deptno int,

birthdate date NOT NULL,

salary int ,

primary key (empno)

)

PARTITION BY range (salary)

(

PARTITION p1 VALUES less than (100),

PARTITION p2 VALUES less than (200)

);

这样的语句会报错。MySQL Database Error: A PRIMARY KEY must include allcolumns in the table's partitioning function;

CREATE TABLE emptt (

empno varchar(20) NOT NULL  ,

empname varchar(20) ,

deptno int(11),

birthdate date NOT NULL,

salary int(11) ,

primary key (empno,salary)

)

PARTITION BY range (salary)

(

PARTITION p1 VALUES less than (100),

PARTITION p2 VALUES less than (200)

);

在主键中加入salary列就正常。

 

2.      MySQL分区处理NULL值的方式

若是分区键所在列没有notnull约束。

若是是range分区表,那么null行将被保存在范围最小的分区。

若是是list分区表,那么null行将被保存到list为0的分区。

在按HASH和KEY分区的状况下,任何产生NULL值的表达式mysql都视同它的返回值为0。

为了不这种状况的产生,建议分区键设置成NOT NULL。

 

3.      分区键必须是INT类型,或者经过表达式返回INT类型,能够为NULL。惟一的例外是当分

区类型为KEY分区的时候,可使用其余类型的列做为分区键( BLOB or TEXT 列除外)。

 

4.      对分区表的分区键建立索引,那么这个索引也将被分区,分区键没有全局索引一说。

5.      只有RANG和LIST分区能进行子分区,HASH和KEY分区不能进行子分区。

6.      临时表不能被分区。

5、获取mysql分区表信息的几种方法

1.     show create table 表名
能够查看建立分区表的create语句

2.     show table status 
能够查看表是否是分区表

3.     查看information_schema.partitions表 
select 
  partition_name part,  
  partition_expression expr,  
  partition_description descr,  
  table_rows  
from information_schema.partitions  where 
  table_schema = schema()  
  and table_name='test';  
能够查看表具备哪几个分区、分区的方法、分区中数据的记录数等信息

4.     explain partitions select语句 经过此语句来显示扫描哪些分区,及他们是如何使用的.

相关文章
相关标签/搜索