MySql分区、分表和分库

数据库的数据量达到一定程度之后 , 为避免带来系统性能上的瓶颈 。需要进行数据的处理 , 采用的手段是分区、分片、分库、分表 。
一些问题的解释:
1.为什么要分表和分区?日常开发中我们经常会遇到大表的情况 , 所谓的大表是指存储了百万级乃至千万级条记录的表 。这样的表过于庞大 , 导致数据库在查询和插入的时候耗时太长 , 性能低下 , 如果涉及联合查询的情况 , 性能会更加糟糕 。分表和表分区的目的就是减少数据库的负担 , 提高数据库的效率 , 通常点来讲就是提高表的增删改查效率 。2.什么是分表?分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表 , 我们可以称为子表 , 每个表都对应三个文件 , MYD数据文件 , .MYI索引文件 , .frm表结构文件 。这些子表可以分布在同一块磁盘上 , 也可以在不同的机器上 。App读写的时候根据事先定义好的规则得到对应的子表名 , 然后去操作它 。3.什么是分区?分区和分表相似 , 都是按照规则分解表 。不同在于分表将大表分解为若干个独立的实体表 , 而分区是将数据分段划分在多个位置存放 , 可以是同一块磁盘也可以在不同的机器 。分区后 , 表面上还是一张表 , 但数据散列到多个位置了 。app读写的时候操作的还是大表名字 , db自动去组织分区的数据 。4.MySQL分表和分区有什么联系呢?(1)都能提高mysql的性高 , 在高并发状态下都有一个良好的表现 。(2)分表和分区不矛盾 , 可以相互配合的 , 对于那些大访问量 , 并且表数据比较多的表 ,  我们可以采取分表和分区结合的方式 , 访问量不大 , 但是表数据很多的表 , 我们可以采取分区的方式等 。(3)分表技术是比较麻烦的 , 需要手动去创建子表 , app服务端读写时候需要计算子表名 。采用merge好一些 , 但也要创建子表和配置子表间的union关系 。(4)表分区相对于分表 , 操作方便 , 不需要创建子表 。分区MySQL的物理数据 , 存储在表空间文件(.ibdata1和.ibd)中 , 这里讲的分区的意思是指将同一表中不同行的记录分配到不同的物理文件中 , 几个分区就有几个.idb文件 。
MySQL在5.1时添加了对水平分区的支持 。
分区是将一个表或索引分解成多个更小 , 更可管理的部分 。
每个区都是独立的 , 可以独立处理 , 也可以作为一个更大对象的一部分进行处理 。这个是MySQL支持的功能 , 业务代码无需改动 。
可以通过使用SHOW VARIABLES命令来确定MySQL是否支持分区 。
MySQL分区类型

  1. RANGE分区:基于一个给定区间边界 , 得到若干个连续区间范围 , 按照分区键的落点 , 把数据分配到不同的分区;
  2. LIST分区:类似RANGE分区 , 区别在于LIST分区是基于枚举出的值列表分区 , RANGE是基于给定连续区间范围分区;
  3. HASH分区:基于用户自定义的表达式的返回值 , 对其根据分区数来取模 , 从而进行记录在分区间的分配的模式 。这个用户自定义的表达式 , 就是MySQL希望用户填入的哈希函数 。
  4. KEY分区:类似于按HASH分区 , 区别在于KEY分区只支持计算一列或多列 , 且使用MySQL 服务器提供的自身的哈希函数 。
RANGE分区把连续区间按范围划分 , 是实战最常用的一种分区类型 , 行数据基于属于一个给定的连续区间的列值被放入分区 。
但是记住 , 当插入的数据不在一个分区中定义的值的时候 , 会抛异常 。RANGE分区主要用于日期列的分区 , 比如交易表啊 , 销售表啊等 。可以根据年月来存放数据 。如果你分区走的唯一索引中date类型的数据 , 那么注意了 , 优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择 。实战中可以用int类型的字段来存时间戳做分区列 , 那么只用存yyyyMM就好了 , 也不用关心函数了 。CREATE TABLE`Order` (`id`INT NOT NULL AUTO_INCREMENT,`partition_key`INT NOT NULL,`amt`DECIMAL(5) NULL) PARTITION BY RANGE(partition_key)PARTITIONS 5(PARTITION part0 VALUES LESS THAN(201901),PARTITION part1 VALUES LESS THAN(201902),PARTITION part2 VALUES LESS THAN(201903),PARTITION part3 VALUES LESS THAN(201904),PARTITION part4 VALUES LESS THAN(201905),PARTITION part4 VALUES LESS THAN MAXVALUE;INSERT INTO `Order` (`id`, `partition_key`, `amt`) VALUES ('1', '201901', '1000');INSERT INTO `Order` (`id`, `partition_key`, `amt`) VALUES ('2', '201902', '800');INSERT INTO `Order` (`id`, `partition_key`, `amt`) VALUES ('3', '201903', '1200');


推荐阅读