关于MySQL分区表、分库分表,可以参考如下文章:
完全理解-MySQL 分区表、分库分表、以及Sharding-JDBC 中间件
1. 垂直拆分
把主键和一些常用的字段放到一个表中,把主键和其他的字段放到另一个表中。
优点:垂直拆分可以使一个数据页放更多的数据,可以较少IO次数。
缺点:查询所需的数据可能需要通过JOIN来查询。
适用场景:表过宽,包含text或blob字段,可以将不常用的列或text/blob列放到另外的表中存储。比如文章表可以将文章内容拆分到另外的表中。
TEXT与BLOB的主要差别就是BLOB保存二进制数据,TEXT保存字符数据。
另外,在数据更新操作时,多表同时更新也比较麻烦。
举一个很常见的业务例子,在分库分表中,要同步更新两个表,这两个表位于不同的物理库中(或者同一库的不同表中),为了保证数据一致性,一种做法是通过分布式事务(或本地事务)将两个更新操作放到一个事务中,但这样的操作一般要加全局锁,性能不太好。
【强制】超过三个表禁止 join。需要 join 的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。《阿里Java开发手册》
2. 水平拆分
根据某一列的值把数据放到多个独立的表中,比如历史数据放到另一张表里。
优点:减少大多数查询读取的数据量,降低索引层数,提高查询速度。
缺点:增加查询复杂度,查询多个表需要使用UNION,或者通过MERGE表。
适用场景:表中数据量过大,历史数据查询次数很少,比如订单信息、操作记录等。
注意:进行水平拆分后的表,字段的列和类型和原表应该是相同的,但是要记得去掉Primary Key字段的auto_increment自增长。
3. 逆规范化
增加冗余列:在多个表中具有相同的列,避免联合查询。
增加派生列:增加的列来自其他表的计算结果,可避免使用函数。
重新组表:将经常联合查询的表组成一个表,减少联合查询。