深入分析mysql数据库表分区

什么是表分区

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

为什么要对表进行分区

为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率。
分区的一些优点包括:

1)、与单个磁盘或文件系统分区相比,可以存储更多的数据。
2)、对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。通常和分区有关的其他优点包括下面列出的这些。MySQL分区中的这些功能目前还没有实现,但是在我们的优先级列表中,具有高的优先级;我们希望在5.1的生产版本中,能包括这些功能。
3)、一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。
4)、涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。
5)、通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

mysql分区类型

根据所使用的不同分区规则可以分成几大分区类型。

RANGE 分区:

基于属于一个给定连续区间的列值,把多行分配给分区。

LIST 分区:

类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。

HASH分区:

基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。

KEY
分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

复合分区:

基于RANGE/LIST 类型的分区表中每个分区的再次分割。子分区可以是 HASH/KEY 等类型。

例子RANGE 分区:

创建表分区range方式,也可以使用hash,list,key

 代码如下 复制代码

create table foo (

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('2009-01-01')),

PARTITION foo_2 VALUES LESS THAN (TO_DAYS('2010-01-01'))

)

增加表分区

ALTER TABLE foo ADD PARTITION(

PARTITION foo_3 VALUES LESS THAN (TO_DAYS('2011-01-01'))

)

插入一条数据

insert into `foo` (`id`, `created`) values (1, '2008-01-02'),(2, '2009-01-02');

分析确认分区是否生效

explain partitions select  * from foo where created = '2008-01-02';

创建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)

);

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

创建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”来修补该分区。

时间: 2024-09-20 15:00:26

深入分析mysql数据库表分区的相关文章

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

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

mysql数据库KEY分区用法

  mysql数据库KEY分区用法 按照KEY进行分区类似于按照HASH分区,除了HASH分区使用的用户定义的表达式,而KEY分区的 哈希函数是由MySQL 服务器提供.MySQL 簇(Cluster)使用函数MD5()来实现KEY分区;对于使用其他存储引擎的表,服务器使用其自己内部的 哈希函数,这些函数是基于与PASSWORD()一样的运算法则. "CREATE TABLE ... PARTITION BY KEY"的语法规则类似于创建一个通过HASH分区的表的规则.它们唯一的区别在

mysql数据库子分区教程

mysql数据库子分区教程 子分区是分区表中每个分区的再次分割.例如,考虑下面的CREATE TABLE 语句: CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE(YEAR(purchased)) SUBPARTITION BY HASH(TO_DAYS(purchased)) SUBPARTITIONS 2 ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES

输出MySql数据库表结构的PHP页面代码

经常为了方便和直观,我们会首先直接在数据库中设计出表,但是接下来又要将表的结构和设计编写在设计文档中,以便编码的时候可以直观的查询,一旦数据库表非常多,字段非常多的时候,这无疑是件非常郁闷的工作. 这是一个漂亮的PHP页面,可以自动输出MySql数据库所有表结构,大大方便了文档的编写工作,也同时非常方便编码的时候进行查询.当然在设计MySql数据库表和字段的时候详细填写表和字段的备注,这是非常好的习惯,对这个网页的输出也是最佳效果的. <!DOCTYPE html PUBLIC "-//W

如何锁定MySQL数据库表

如果你同时运行表的检查/修复程序时,你或许不想让MySQL服务器和实用程序同时访问一个表.如果两个程序都向表中写数据显然会造成很大的麻烦,甚至会有意外情况发生.如果表正由一个程序写入,同时进行读取的另一个程序也会产生混乱的结果.本文主要讲述如何对MySQL数据库表进行锁定. 锁定表的方法 防止客户机的请求互相干扰或者服务器与维护程序相互干扰的方法主要有多种.如果你关闭数据库,就可以保证服务器和myisamchk和 isamchk之间没有交互作用.但是停止服务器的运行并不是一个好注意,因为这样做会

教你MySQL数据库表的故障检测

你可能在使用MySQL过程中,各种意外导致数据库表的损坏,而且这些数据往往是最新的数据,通常不可能在备份数据中找到.本章将讲述如何检测MySQL数据库表的故障. 表的故障检测和修正的一般过程如下: ◆ 检查出错的表.如果该表检查通过,则完成任务,否则必须修复出错的数据库表. ◆ 在开始修复之前对表文件进行拷贝,以保证数据的安全. ◆ 开始修复数据库表. ◆ 如果修复失败,从数据库的备份或更新日志中恢复数据. 在使用myisamchk或isamchk检查或修复表之前,应该首先注意: ◆ 建立数据库

mysql数据库表操作,求解答

问题描述 mysql数据库表操作,求解答 现在有一张emp表,表中有8个字段,emp表中有数据,怎样再增加一个字段,设置成主键,自增 解决方案 alter table emp add id int auto_increment,add primary key(id) 解决方案二: ALTER TABLE emp ADD PRIMARY KEY id AUTO_INCREMENT

tomcat-使用eclipse创建mysql数据库表

问题描述 使用eclipse创建mysql数据库表 为什么我在eclipse配置好了映射文件,启动tomcat没有报错,但是mysql数据库没有创建表 解决方案 启动tomcat有没有执行了创建表的sql语句吗 解决方案二: 查看你关联的数据库有没有?配置文件有没有写错? 解决方案三: 使用PowerDesigner创建mysql数据库表使用Navicat将mysql中的数据导出--包括数据库表创建脚本和数据使用PowerDesigner创建mysql数据库表图文并茂版 解决方案四: 那是不是你

将mysql数据库表中的部分数据导入到oracle数据库中

问题描述 将mysql数据库表中的部分数据导入到oracle数据库中 有一个问题:需要将Mysql数据库表中的某些数据导入oracle数据库的表中,需要通过传递文件来实现.比如将mysql数据生成.sql文件,然后执行该文件就可以写入到oracle数据库中.希望各位高手给个思路,谢谢 解决方案 可以用sql命令把数据导出到文件,e然后再把文件导入数据库 解决方案二: 你自己思路不是已经很清晰了吗? or你的意思是需要定时自动导入? 自动导入的话 估计需要借助写个程序实现了 解决方案三: 你自己思