分区表是mysql5.1之后的新特性,合并表已经存在很长时间了。这篇文章主要介绍这两个概念以及他们基本的操作。

一、合并表

合并表说实话是一种将要被淘汰的技术,但是掌握了合并表的概念再去看分区表就比较容易理解一点。

合并表其实就是合并了多个子表的逻辑表,子表使用了myisam存储引擎物理子表,合并表使用merge存储引擎,逻辑表和子表的结构完全相同(包括字段、索引等)。

删除一个合并表,它的子表不会受任何影响,而如果删除其中一个子表则可能会有不同的后果,这要视操作系统而定。

下面我们进行实操一下:创建量两张物理子表t1和t2,然后创建他们俩的合并表。

 1#创建表t1和t2,存储引擎是myisam
2mysql> create table t1( data int not null primary key )engine=myisam;
3Query OK, 0 rows affected (0.00 sec)
4mysql> create table t2( data int not null primary key )engine=myisam;
5#创建合并表,存储引擎是merge
6mysql> create table t3( data int not null primary key )
7    engine=merge union=(t1,t2) insert_method=last;
8Query OK, 0 rows affected (0.00 sec)
9#下面插入数据:t1插入123,t2插入234
10Query OK, 0 rows affected (0.01 sec)
11mysql> insert into t1 values(1),(2),(3);
12Query OK, 3 rows affected (0.01 sec)
13Records: 3  Duplicates: 0  Warnings: 0
14mysql> insert into t2 values(2),(3),(4);
15Query OK, 3 rows affected (0.00 sec)
16Records: 3  Duplicates: 0  Warnings: 0

在上面我们进行了一些初始化操作。而且我们在创建合并表的时候,指定了insert_method为last,意思就是在最后一张物理表的末尾插入真实数据,这里最后一张真实物理表就是t2。此时我们插入一个数据5会发现:t1没有,t2有。

 1mysql> insert into t3 values(5);
2Query OK, 1 row affected (0.00 sec)
3mysql> select * from t1;
4+------+
5| data |
6+------+
7|    1 |
8|    2 |
9|    3 |
10+------+
113 rows in set (0.00 sec)
12mysql> select * from t2;
13+------+
14| data |
15+------+
16|    2 |
17|    3 |
18|    4 |
19|    5 |
20+------+
214 rows in set (0.00 sec)

合并表的内容很简单,也很容易理解。既然表能合并肯定也能分开。我们接着看分区表:

二、分区表

分区表就是把一张表分开,对用户来说,分区表是一个独立的逻辑表,但是底层由多个物理子表组成。实现分区的代码实际上是对一组底层表的句柄对象的封装。对分区表的请求,都会通过句柄对象转化成对存储引擎的接口调用。分区表的每一个分区都是有索引的独立表。

分区表发挥大作用的场景:

(1)表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。

(2)分区表的数据更容易维护。

(3)分区表的数据可以分布在不同的物理设备上。

(4)可以使用分区表来避免某些特殊的瓶颈,例如InnoDB单个索引的互斥访问。

(5)如果需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好。

分开的方式有三种:

(1)水平分区:根据行切分,也就是把记录分开。

(2)垂直分区:根据列切分,也就是把字段分开。

(3)复合分区:水平分区和垂直分区的结合。

我们按照这两种方式来实际操作一下:

1、水平分区

(1)range分区

range分区是基于连续的范围值。

 1mysql> create table t4(
2    -> id int not null,
3    -> score int 
4    -> )
5    -> partition by range(score)
6    -> (
7    -> partition s1 values less than(60),
8    -> partition s2 values less than(80),
9    -> partition s3 values less than(90),
10    -> partition s4 values less than maxvalue
11    -> );
12#下面开始插入数据
13mysql> insert into t4 values (1,69),(2,85),(3,100),(4,5);
14#删除某个范围内的用户,只需要删除相应的分区即可
15mysql> alter table t4 drop partition s2;

在这里需要注意的是,alter形式删除分区比delete形式更加的高效。一般都是基于日期时间进行分区。

(2)List分区

range分区是基于连续的范围,list是基于确定值的范围,就好比集合。

 1mysql> create table t5(
2    -> name varchar(20),
3    -> socre int,
4    -> no int
5    -> )
6    -> partition by list (no)
7    -> (
8    -> partition n1 values in (10,20),
9    -> partition n2 values in (30),
10    -> partition n3 values in (40)
11    -> );

这种不是指的范围,而是指的具体的值,10号和20在n1分区,30在n2分区。

(3)Hash分区

hash分区指的是根据hash运算的模,最终确定在哪一个分区。比如2020/4=0,就落在分区0上。

 1mysql> create table t6(
2    -> id int,
3    -> name varchar(20),
4    -> birth date not null,
5    -> socre int
6    -> )
7    -> partition by hash (year(birth))
8    -> partitions 4;
9#插入一条数据
10mysql> insert into t6 values(1,'fdd','2020-01-20',99);
11Query OK, 1 row affected (0.00 sec)

此时我们2020/4=0,就会保存在分区0中。

(4)线性Hash分区

线性hash指的是使用2的幂运算法则。运算起来比较麻烦。但是优点是可以使得数据分布均匀。举个例子。假设分区个数num=6,N表示数据最终存储的分区:

第一步:V = power(2, ceiling(log(2, num))),log是计算NUM以2为底的对数,ceiling()向上取整,power()是取2的次方值;

第二步:N=values&(V-1),&位与运算,

第三步:while N>=num,此时N =N & (CEIL(V/ 2) - 1)

比如插入2020-01-20,V=8,N=(2020)& (8-1)=4。4<6,所以保存在分区4。

代码就不演示了,区别就是by hash换成by linear hash。

2、垂直分区

垂直分区比较少,直接通过key字段名进行划分即可。

1mysql> create table t7(
2    -> id int,
3    -> name varchar(20),
4    -> no int,
5    -> score int
6    -> )
7    -> partition by key(id)
8    -> partitions 4;
9Query OK, 0 rows affected (0.03 sec)

垂直分区相当简单。

3、复合分区

上面介绍了水平和复合的方式,复合分区的方式是进行组合。你可以随意搭配。这里演示一种。

 1mysql> create table t8(
2    -> id int,
3    -> name varchar(20),
4    -> birth date not null,
5    -> score int
6    -> )
7    -> partition by list (id)
8    -> subpartition by key (birth)
9    -> subpartitions 4
10    -> (
11    -> partition p1 values in (10),
12    -> partition p2 values in (20,30)
13    -> );
14Query OK, 0 rows affected (0.04 sec)

父分区使用list,子分区使用垂直分区。

在这里介绍了分区表的一些概念和基础的使用方法。其实分区表也有很多限制。

分区表的限制:

(1)一个表最多只能有1024个分区。

(2)如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。

(3)分区表中无法使用外键约束。

(4)所有分区都必须使用相同的存储引擎。

(5)某些存储引擎不支持分区。比如说merge、InnoDB、CSV、联合存储引擎等。

MERGE存储引擎。 用户定义的分区和MERGE 存储引擎不兼容。分区表无法合并。

联合存储引擎。FEDERATED不支持 分区表; 不可能创建分区 FEDERATED表。

CSV存储引擎。CSV不支持使用存储引擎的分区表; 不可能创建分区CSV表。

InnoDB存储引擎。InnoDB外键和MySQL分区不兼容。分区 InnoDB表不能有外键引用,也不能有外键引用的列。InnoDB具有或由外键引用的表不能分区。

(6)对于MyISAM表,使用分区表时需要打开更多的文件描述符。

所以在使用的时候一定要注意。


更多相关文章

  1. linux下如何格式化NTFS分区
  2. 100%高度分区内显示:表格单元分区
  3. 请教mysql表分区后性能问题
  4. MySQL 分区表 partition线上修改分区字段,后续进一步学习partitio
  5. 在原最大分区基础上再增加分区方法
  6. Mysql PARTITION 数据表分区技术
  7. Linux入门笔记之一:系统分区及挂载点
  8. linux挂载分区后重启失败
  9. linux中的磁盘分区

随机推荐

  1. 计算mysql中每天的发生次数
  2. 为获得快速结果,我的查询有什么好的索引?
  3. 读《SQL优化核心思想》:你不知道的优化技
  4. Android如何通过JDBC直连访问MySQL数据库
  5. MySQL各模块工作配合
  6. mysql主从同步(4)-Slave延迟状态监控
  7. Windows下DOS命令大全
  8. Mysql Where使用列别名
  9. mysql存储过程的使用
  10. mysql组并对UNION进行排序