MySQL之分区表初识_mysql

一、分区表介绍

     ​定义: ​ mysql分区表 通俗地讲表分区是将一大表,根据条件分割成若干个小表.  表的不同行可以分配给不同的物理分区。

              比如:某用户表的记录超过了1000万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区。当然也可根据其他的条件分区。

     功能:  改善大表以及具有各种访问模式的表的可伸缩性和提高数据库查询效率。更方便的进行大表数据进行归档备份

   ​  优点:

        1)、与单个磁盘或文件系统分区相比,可以存储更多的数据。

        2)、对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。

        3)、一些查询语句可以得到优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。

       4)、涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。

       5)、通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

     ​缺点:​ 较多.​尽量避免分区表,分区表性能问题:体现在分区锁,初期访问加载所有分区。

二、mysql分区表限制条件

2.1、开源版mysql限制条件

       1) MySQL 8.0不支持垂直分区,其中一个表的不同列被分配到不同的物理分区。 目前没有计划将垂直分区引入 MySQL.

       2) 要创建分区表,您必须使用支持它们的存储引擎。 在 MySQL 8.0 中,同一个分区表的所有分区必须使用相同的存储引擎

       3) 在 MySQL中,唯一支持分区的存储引擎是 InnoDB 和 NDB。 不支持分区的存储引擎不能使用分区; 其中包括 MyISAM、MERGE、CSV 和 FEDERATED 存储引擎。

       4) ​禁止的构造。 分区表中不允许使用以下结构:存储过程、存储函数、可加载函数或插件。不允许声明的变量或用户变量。

       5) 算术和逻辑运算符。 在分区表达式中允许使用算术运算符 +、- 和 *。 但是,结果必须是整数值或 NULL 

       6) 不允许使用 / 运算符。位运算符 |、&、^、<<、>> 和 ~ 在分区表达式中是不允许的。

       7) 许多 MySQL 函数和运算符的结果可能会根据服务器 SQL 模式而改变。 因此,在创建分区表后随时更改 SQL 模式可能会导致此类表的行为发生重大变化,并且很容易导致数据损坏或丢失。 由于这些原因,强烈建议您在创建分区表后永远不要更改服务器 SQL 模式。

       8) ​服务器SQL_mode影响分区表的同步复制。 主机和从机上的不同SQL_mode可能会导致sql语句; 这可能导致分区之间的数据分配给定主从位置不同,甚至可能导致插入主库上成功的分区表在从库上失败。 为了获得最佳效果,您应该始终在主机和从机上使用相同的服务器SQL模式​。

       9) 文件系统操作。 分区和重新分区操作(例如使用 PARTITION BY ... 的 ALTER TABLE、REORGANIZE PARTITION 或 REMOVE PARTITIONING)取决于文件系统操作的实现。 这意味着这些操作的速度受文件系统类型和特性、磁盘速度、交换空间、操作系统的文件处理效率以及与文件处理相关  的 MySQL 服务器选项和变量等因素的影响

     10) mysql分区数量最大支持到​8192个(包括子分区)

     11) 对表执行分区操作(新增和删除)的进程会对该表进行写锁定。同时对表进行DDL操作时,这个表的所有的分区都会被锁,表越大,分区越多 锁时间越长。 此类表的读取相对不受影响; 分区操作完成后立即执行挂起的 INSERT 和 UPDATE 操作。

     12) 在某些情况下,出于其他考虑,使用大量(数百个)分区可能也不可取,因此使用更多分区并不会自动产生更好的结果。

     13) ​分区键必须包含在表的所有主键、唯一键中。

     14. MYSQL只能在使用分区函数的列本身进行比较时才能过滤分区,而不能根据表达式的值去过滤分区,即使这个表达式就是分区函数也不行。

     15) 不支持查询缓存: 分区表不支持查询缓存,对于涉及分区表的查询,它自动禁用。 查询缓存无法启用此类查询。

     16) ​分区的innodb表不支持外键。分区表无法使用外键约束。

     17) 针对分区表运行的 ALTER TABLE ... ORDER BY 列语句会导致仅在每个分区内对行进行排序。

     18) ​全文索引。 分区表不支持全文索引,即使是使用InnoDB或MyISAM存储引擎的分区表。

     19) 在分区表上执行 ALTER TABLE ... ADD COLUMN ... ALGORITHM=INSTANT 后,将无法再与该表交换分区。

     20) 修改主键对 REPLACE 语句的影响: 如果存在需要修改表的主键。请注意,如果您的应用程序使用 REPLACE 语句,则这些语句的结果可能会发生巨大变化。

     21) ​FULLTEXT 索引。分区表不支持 FULLTEXT 索引或搜索。

     22) 空间列。具有空间数据类型(如 POINT 或 GEOMETRY)的列不能在分区表中使用。

     23) 临时表。临时表不能分区。

     24) 日志表。无法对日志表进行分区;对此类表的 ALTER TABLE ... PARTITION BY ... 语句失败并出现错误。

     25) 分区键的数据类型。分区键必须是整数列或解析为整数的表达式。不能使用使用 ENUM 列的表达式。列或表达式值也可能为 NULL。

     26) ​subpartition问题: subpartition必须使用HASH或KEY分区。 只有RANGE和LIST分区可能被分区; HASH和KEY分区不能被子分区。

     27) 分区表不支持mysqlcheck,myisamchk和myisampack。

2.2、阿里云RDS库分区表限制条件

      只能对数据表的整型列进行分区,或者数据列可以通过分区函数转化成整型列。 最大分区数目不能超过1024。 如果含有唯一索引或者主键,则分区列必须包含在所有的唯一索引或者主键在内。 不支持外键。 不支持全文索引(FULL TEXT)

      阿里官方和业内都不推荐采用分区表,因为mysql分区表的限制条件太多。

三、分区表类型

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

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

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

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

主要是以上四大类。后面在mysql5.5引入了COLUMN分区分区功能,只有RANGE COLUMN和LIST COLUMN这两种分区;支持整形、日期、字符串;RANGE和LIST的分区方式非常的相似。

COLUMNS和RANGE和LIST分区的区别

1)针对日期字段的分区就不需要再使用函数进行转换了,例如针对date字段进行分区不需要再使用YEAR()表达式进行转换。

2)COLUMN分区支持多个字段作为分区键但是不支持表达式作为分区键。

column支持的数据类型:

1)所有的整型,float和decimal不支持

2)日期类型:date和datetime,其他不支持

3)字符类型:CHAR, VARCHAR, BINARY和VARBINARY,blob和text不支持 

后面又在mysql5.6版本引入了复合分区的功能,复合分区​只支持RANGE和LIST的子分区,且子分区的类型只能为HASH和KEY。


参考mysql官方文档说明:​

​​​​​https://dev.mysql.com/doc/refman/8.0/en/partitioning-overview.html​​​

https://dev.mysql.com/doc/refman/8.0/en/partitioning-limitations.html