分区是根据必定的规则,数据库把一个表分解成多个更小的、更容易管理的部分。就访问数据库应用而言,逻辑上就只有一个表或者一个索引,但实际上这个表可能有N个物理分区对象组成,每一个分区都是一个独立的对象,能够独立处理,能够做为表的一部分进行处理。分区对应用来讲是彻底透明的,不影响应用的业务逻辑。分区有利于管理很是大的表,它采用分而治之的逻辑,分区引入了分区键的概念,分区键用于根据某个区间值(或者范围值)、特定值列表或者hash函数值执行数据的汇集,让数据根据规则分布在不一样的分区中,让一个大对象分割为一些小对象。mysql
range 分区:基于一个给定的连续区间范围(区间要求连续而且不能重叠),把数据分配到不一样的分区
list 分区:相似于range分区,区别在于list分区是居于枚举出的值列表分区,range是基于给定的连续区间范围分区
hash 分区:基于给定的分区个数,把数据分配到不一样的分区
key 分区:相似于hash分区sql
注意:不管哪一种分区,要么你分区表上没有主键/惟一键,要么分区表的主键/惟一键都必须包含分区键,也就是说不能使用主键/惟一键字段以外的其它字段分区。
若是你想在分区表使用时间字段来做为分区键,你应该把ID和时间字段设为分区表的组合主键。数据库
1.和单个磁盘或者文件系统分区相比,能够存储更多数据
2.优化查询。在where子句中包含分区条件时,能够只扫描必要的一个或者多个分区来提升查询效率;同时在涉及sum()和count()这类聚合函数的查询时,能够容易的在每一个分区上并行处理,最终只须要汇总全部分区获得的结果
3.对于已通过期或者不须要保存的数据,能够经过删除与这些数据有关的分区来快速删除数据
4.跨多个磁盘来分散数据查询,以得到更大的查询吞吐量less
经过show variables like ‘%datadir%’;命令查看mysql的data存放目录,进入所在的数据库目录。不一样的引擎数据库文件格式不一样。函数
mysql> show variables like '%datadir%'; +---------------+---------------------------------------------+ | Variable_name | Value | +---------------+---------------------------------------------+ | datadir | C:\ProgramData\MySQL\MySQL Server 5.7\Data\ | +---------------+---------------------------------------------+
innodb: 只有设置成独立表空间才能作成功表分区
.frm : 表结构
.ibd : 数据 + 索引优化
MySQL有五种分区类型 range、list、hash、key、子分区,其中最经常使用的是range和list分区spa
首先须要肯定你使用的数据库有没有开启分区功能插件
-- 查看mysql版本
select version( ) , mysql5.1开始支持数据表分区code
-- 查看分区插件是否激活 partition active
show plugins; 对象
(1) range分区
给定一个连续区间的范围值进行分区,某个字段的值知足这个范围就会被分配到该分区。适用于字段的值是连续的区间的字段,如 日期范围, 连续的数字。
-- 语法
create table <table> ( // 字段 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 partition by range (分区字段) ( partition <分区名称> values less than (Value), partition <分区名称> values less than (Value), ... partition <分区名称> values less than maxvalue );
-- 字段介绍
range:表示按范围分区
分区字段:表示要按照哪一个字段进行分区,能够是一个字段名,也能够是对某个字段进行表达式运算如year(create_time),使用range最终的值必须是数字
分区名称: 要保证不一样,也能够采用 p0、p一、p2 这样的分区名称,
less than : 表示小于
Value : 表示要小于某个具体的值,如 less than (10) 那么分区字段的值小于10的都会被分到这个分区
maxvalue: 表示一个最大的值
注意:range 对应的分区键值必须是数字值,可使用range columns(分区字段) 对非int型作分区,如字符串,对于日期类型的可使用year()、to_days()、to_seconds()等函数。
-- 建立方式
分区能够在建立表的时候进行分区,也能够在建立表以后进行分区
alter table <table> partition by RANGE(id) ( PARTITION p0 VALUES LESS THAN (1000000), PARTITION p1 VALUES LESS THAN (2000000), PARTITION p2 VALUES LESS THAN (3000000), PARTITION p3 VALUES LESS THAN (4000000), PARTITION p4 VALUES LESS THAN MAXVALUE ); CREATE TABLE `tbl_user_part` ( `id` int(11) NOT NULL , `username` varchar(255) DEFAULT NULL, `email` varchar(20) DEFAULT NULL, `age` tinyint(4) DEFAULT NULL, `type` int(11) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP -- PRIMARY KEY (`id`,`age`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 PARTITION BY RANGE (age) ( PARTITION p0 VALUES LESS THAN (20), PARTITION p1 VALUES LESS THAN (40), PARTITION p2 VALUES LESS THAN (60), PARTITION p3 VALUES LESS THAN (80), PARTITION p4 VALUES LESS THAN MAXVALUE );
-- 常见错误
在建立分区的时候常常会遇到这个错误:A PRIMARY KEY must include all columns in the table’s partitioning function。意思是说分区的字段必须是要包含在主键当中。
可使用PRIMARY KEY (id,xxx)来将多个字段做为主键。在作分区表时,选择分区的依据字段时要谨慎,须要仔细斟酌这个字段拿来作为分区依据是否合适,这个字段加入到主键中作为复合主键是否适合。
(2) list 分区-- 语法
create table <table> ( // 字段 ) ENGINE=数据库引擎 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 partition by LIST (分区字段或者基于该字段的返回的整数值的表达式) ( partition <分区名称> values IN (Value1,Value2, Value3), ... partition <分区名称> values IN (Value4, Value5), );
(3) 关于 hash 和 key 分区这里不作介绍.........
mysql提供了添加、删除、重定义、合并、拆分分区的命令,这些操做均可以经过alter table 命令来实现
-- 删除list或者range分区(同时删除分区对应的数据) alter table <table> drop partition <分区名称>; 注意: 删除分区的同时会删除数据 -- 取消分区,不删除数据 alter table <table> remove partitioning; -- range添加新分区 alter table <table> add partition(partition p4 values less than MAXVALUE); 注意:RANGE 的分区方式在加分区的时候,只能从最大值后面加,而最大值前面不能够添加 -- list添加新分区 alter table <table> add partition(partition p4 values in (25,26,28));