MySQL分表分区是解决MySQL数据量大导致性能低下的两种方法。什么是MySQL分表从表面上看,MySQL分表就是把一个表分成多个表,数据和数据结构可能会发生变化。MySQL分片分为垂直分片和水平分片。1.垂直分表垂直分表是按照表格中的字段进行分表,如下图所示。在上图中,我们将原本分布在同一张表中的C1、C2、C3、C4这四个字段,垂直的分成了两个表。第一个表中分布了三个字段C1、C3、C4,第二个表中分布了两个字段C1、C2。两个拆分表通过公共字段C1关联。2.水平分表水平分表是根据表中的记录来划分的。如下所示。上图中,我们将原本分布在同一张表中的4条记录横向拆分为两个表。在第一个表中,分布了两条记录;在第二张表中,分布了两条记录。3、分表操作MySQL分表不仅可以自定义规则,也可以使用业界通用的规则,或者使用merge存储引擎来实现。1)自定义规则按用户或业务号分表。pair和用户或者业务可以按照%n的个数分成n个表。按日期排序。用于日志或统计类等的表。可按年、月、日、周分表。2)使用Merge存储引擎使用Merge存储引擎实现MySQL分表更适合那些没有提前考虑分表的人。随着数据的增多,数据查询变慢了。使用Merge存储引擎实现MySQL表分区可以避免代码更改。使用Merge实现MySQL分表可以按照如下形式进行操作:上图中ENGINE=MERGE表示使用了merge引擎。另外,ENGINE=MRG_MyISAM同义。UNION=(user1,user2)表示挂载user1和user2表,INSERT_METHOD=LAST表示插入方式:0不允许插入,FIRST插入UNION中的第一个表,LAST插入最后一个表中联盟。使用Merge存储引擎实现MySQL分表。分表的结果会分为主表和分表。主表类似于一个外壳,逻辑上封装了子表。实际上,数据是存储在分表中的。如下所示。上图是user表合并子表的结果,alluser为主表,user1和user2为子表。每个表都有自己的表结构,子表也保存数据和索引,主表不保存数据和索引,主表只保存子表之间的关系和插入数据的方式。4、分表查询对于分表后的查询操作,依然是联合查询、查看等基本操作,或者使用mergeengine对这个表中的数据进行合并查询。一些复杂的操作需要借助存储过程来完成,分表的管理是借助外部工具来实现的。比如垂直表分区使用join连接,水平表分区使用union连接。对于使用Merge存储引擎实现的MySQL分表,可以直接查询总表。5、注意事项1)重复记录/重复索引如果在创建Merge表之前,子表t1/t2已经存在,并且t1/t2中存在重复记录。查询时,返回满足记录的条目。表示只会显示一条记录,不会报错。Merge表创建后insert/update时如果出现重复索引,会提示错误。MERGE表只负责创建表后的操作。2)如何删除子表不能直接删除子表,会破坏Merge表。正确的方法是:altertabletENGINE=MRG_MyISAMUNION=(t1)INSERT_METHOD=LAST;滴片1;3)误删Merge表不会造成数据丢失,重新建表即可。什么是MySQL分区从表面上看,MySQL分区就是把一个表的数据分成多个存储块,而数据结构不变。另外,这些存储块可以在同一个磁盘上,也可以在不同的磁盘上。如下所示。上图是表aa分区后文件在磁盘上的分布情况。从图中可以看出,aa表分区后数据结构没有变化,数据和索引存储的位置由原来的一个变成了两个。此外,还有一个额外的.par文件。打开.par文件后,可以看到里面记录了这张表的分区信息。1、分区操作MySQL从5.1.3开始支持Partition。可以使用如下命令确认你的版本是否支持Partition:MySQL支持的分区类型包括Range、List、Hash、Key,Range是比较常用的:1)Range(范围)——这种模式允许DBA将数据分成不同的范围。例如,DBA可以将一张表按年份划分为三个分区,80年代(1980年代)的数据,90年代(1990年代)的数据,2000年之后(包括2000年)的任何数据。如下:这里将user表分为4个分区,以每300万条记录为界,每个分区都有自己独立的数据和索引文件存放目录。2)List(predefinedlist)——这种模式允许系统按照DBA定义的list的值来拆分行数据。例如:DBA根据用户类型进行分区。3)Key(键值)——上述Hash方式的扩展,HashKey由MySQL系统生成。4)Hash(散列)——这种模式允许DBA计算表的一个或多个列的HashKey,最终划分Hash码不同值对应的数据区。例如,DBA可以创建一个对表的主键进行分区的表。2、注意事项1)对于以上的每一种分区方式,这些分区所在的物理磁盘都可以分开,完全独立,以提高磁盘IO吞吐量。如下:上图是Range(范围)分区类型的物理空间分离操作。2)虽然分区很酷,但是目前的实现还是有很多局限性:主键或者唯一索引必须包含分区字段:比如PRIMARYKEY(i,created)。在很多情况下,使用分区时不要使用主键,否则可能会影响性能。只能按int类型的字段或返回类型int的表达式进行分区:通常使用YEAR或TO_DAYS等函数。每张表最多1024个分区:不能无限扩展分区,过度使用分区往往会消耗大量系统内存。分区表不支持外键:相关约束逻辑必须以编程方式实现。MySQL分表和分区的异同可以提高MySQL的性能,在高并发状态下有很好的表现。分表和分区并不矛盾,可以相互配合。对于那些访问量大,表数据量大的表,我们可以采用分表和分区相结合的方式(如果merge的分表方式不能配合分区,可以使用其他分表来测试),而且访问量不大,但是表数据很多,我们可以采用分表等方法,分表技术繁琐,需要手动创建分表,分表-应用服务器读写时需要计算表名。用merge比较好,但是也需要创建子表,并配置子表之间的联合关系。与分表相比,分表操作简单,不需要创建分表。
