我发现我在工作中分区场景没有特别的多,更多时候我们会去讨论进行分库分表要怎么分,所以本篇博客我把分区和分库分表合并在一起。
MySQL在5.1版本添加了对分区的支持
- CREATE TABLE `PARTITION_TESt` (
- `id` int(32) NOT NULL,
- `year` datetime NOT NULL,
- PRIMARY KEY(`id`,`year`)
- ) partition by range columns(year)
- (PARTITION `1990` VALUES LESS THAN (1990),
- PARTITION `1991` VALUES LESS THAN (1991),
- PARTITION `1992` VALUES LESS THAN (1992)
- );
- insert into t values(1,'1990-01-01'),(2,'1991-01-01');
物理上这个表或索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。
但是就访问数据库的应用而言,从逻辑上讲,只有一个表或一个索引
| session A | session B | |
| T1 | begin; select * from PARTITION_TESt where year='1990-12-25' for update; | |
| T2 | insert into PARTITION_TESt values(1,'1990-12-29'); (block) insert into PARTITION_TESt values(1,'1991-01-02'); (success) |
在非分区的情况下在拥有1990-01-01和1991-12-30下上面的执行结果两个insert语句会堵塞,但是在使用分区表后,因为表被分割成两个物理区间,因此只有1990下的insert语句会堵塞。
| session A | session B | |
| T1 | begin; select * from PARTITION_TESt where year='1990-12-25'; | |
| T2 |
alter table PARTITION_TESt truncate partition 1990 (block) |
server 层看的话,一个分区表就只是一个表,所有分区共用同一个 MDL 锁。
分区表不能建立太多的分区,分区表分区过多导致的主从延迟问题
虽然物理上分有多个ibd组成,但是实际上在做不同分区的DML操作和DDL、DML操作的时候会出现MDL锁
分区表不是用于提升MySQL的性能,而是在于方便数据管理
通过非DBA人员从零到一,MySQL InnoDB数据库调优之路(一)-建表可知道InnoDB的存储量与B+树高度的关系,虽然使用分区表使我们数据分散到多个物理分区,但是并没有多大的提升,举个例子把三层2000万整表数据分区成2000个2层10000数据的分区表,在访问数据时候也只是减少了1次IO,实际上没有对性能有显著的提升。
面试的时候面试官经常会问你们有用分库分表吗,首先我认为分库分表不是公司技术发展的必然结果,根据我实际的工作经验来看,使用分库分表会是有以下几种原因导致:
在我实际碰到和了解到的场景会因为内容域的不同形成垂直库拆分和水平库拆分,除此之外读写分离我觉得也是一种特殊类型的分库手法。



分表的原因就比较好理解,归根究底就是流量和数据量增大,单表容量引起查询负载会陡然增长导致查询需要更多耗时长,因此通过拆分数据表保证单表数据在合适的范围内。分表也分为垂直拆分与水平拆分


分区表是一个时代的产物,那个时代开源数据库中间件不发达,访问就只能由数据库来进行分区,在发表这篇博文的近几年里,开源的数据库中间件已经非常成熟,如ShardingSphere系列组件它们:
分区表始终没有办法突破单表的性能瓶颈,如其长时间对单表数据库参数,服务机硬件升级。不如使用分表在短时间内能看到成效。
对于分表是我对数据库调优中的加法方式,后面我会通过减法来进一步阐述我对数据库调优的理解。