文章目录
- 1 分区表概念
- 2 分区表应用场景
- 3 分区表局限性
- 4 分区表原理
- 5 分区表类型
- 6 分区表使用
- 7 在使用分区表的时候需要注意的问题
1 分区表概念
分区表即按照一定规则将一个表的数据存储在多个表中,并且在物理内存中使用独立的数据文件。
2 分区表应用场景
分区表有以下应用场景:
- 表非常大以至于无法将全部数据放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。
- 分区表的数据更容易维护,比如批量删除大量数据可以使用清除整个分区的方式。另外,分区表使得对一个独立分区进行优化、检查、修复等操作更加容易。
- 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
- 可以使用分区表来避免某些特殊的瓶颈,比如innodb的单个索引的互斥访问和ext3文件系统的inode锁竞争等。
- 可以备份和恢复独立的分区,有时候备份数据或者恢复数据可能并不需要针对全量数据,使用分区表可以减少I/O消耗。
3 分区表局限性
分区表也存在一些局限性:
- 一个表最多只能有1024个分区,在5.7版本的时候可以支持8196个分区。
- 在早期的mysql中,分区表达式必须是整数或者是返回整数的表达式,在mysql5.5中,某些场景可以直接使用列来进行分区。
- 如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。
- 分区表无法使用外键约束。
4 分区表原理
分区表由多个相关的底层表实现,这个底层表也是由句柄对象标识,我们可以直接访问各个分区。存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分区表的索引知识在各个底层表上各自加上一个完全相同的索引。从存储引擎的角度来看,底层表和普通表没有任何不同,存储引擎也无须知道这是一个普通表还是一个分区表的一部分。
5 分区表类型
- 范围分区:根据列值在给定范围内将行分配给分区。
- 列表分区:类似于按range分区,区别在于list分区是基于列值匹配一个离散值集合中的某个值来进行选择。
- 列分区:mysql从5.5开始支持column分区,可以认为是range和list的升级版,在5.5之后,可以使用column分区替代range和list,但是column分区只接受普通列不接受表达式。(实际上没什么卵用)
- Hash分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含myql中有效的、产生非负整数值的任何表达式。
- Key分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含myql中有效的、产生非负整数值的任何表达式。(更加没卵用)
- 子分区:在分区的基础之上,再进行分区后存储。
6 分区表使用
试想如果需要从非常大的表中查询出某一段时间的记录,而这张表中包含很多年的历史数据,数据是按照时间排序的,此时应该如何查询数据呢?因为数据量巨大,肯定不能在每次查询的时候都扫描全表。考虑到索引在空间和维护上的消耗,也不希望使用索引,即使使用索引,也会产生大量的碎片,还会产生大量的随机IO,而且当数据量超大的时候,索引也就无法起作用了,此时就可以考虑使用分区来解决。
分区表的使用有两种方式:
- 全量扫描数据,不要任何索引。使用简单的分区方式存放表,不要任何索引,根据分区规则大致定位需要的数据为止,通过使用where条件将需要的数据限制在少数分区中,这种策略适用于以正常的方式访问大量数据。
- 索引数据,并分离热点。如果数据有明显的热点,而且除了这部分数据,其他数据很少被访问到,那么可以将这部分热点数据单独放在一个分区中,让这个分区的数据能够有机会都缓存在内存中,这样查询就可以只访问一个很小的分区表,能够使用索引,也能够有效的使用缓存。
7 在使用分区表的时候需要注意的问题
- null值会使分区过滤无效。
- 分区列和索引列不匹配,会导致查询无法进行分区过滤。
- 选择分区的成本可能很高。
- 打开并锁住所有底层表的成本可能很高。
- 维护分区的成本可能很高。