一、简述
&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;传统的关系型数据库,比如常用的 MySQL 都存在性能瓶颈,即在数据达到一定的量级之后,数据库的性能会显著下降,数据库的读写操作都会随之受到影响。这是一个常见的性能优化场景。对此,也有一些常见的优化思路:
- NoSQL:工作中比较常用的如Redis用来缓解数据库的压力。将热点数据预热到缓冲中,避免大量的访问压力直接给到数据库上面,给数据库减轻负担。
- 读写分离:配置实现主从数据库,将请求分为读/写两种类型,读请求走从库(slave),写类型请求走主库(master)。比如MySQL自身提供的主从数据同步方案。主从库之存在较低(可接受范围)的数据同步延迟。
- 数据分片。如果单表/单库存在数据保存的性能问题,可使用分片将保存的数据分散到多个库表中,其中分为水平分片和垂直分片,两种分片方式各有优缺点和适用的场景。下面来逐一介绍一下两种分片方式的差异。
二、水平分片与垂直分片
2.1 水平分片
&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;按照统一类型的数据,分别放到不同的库/表中。每个分片包含了整体的数据集合的一部分。如:
- 根据主键id拆分,奇数id的数据保存奇数表(db01.t_user_01,db02.t_user_03),偶数 id 的数据保存在偶数表(db01.t_user_02,db02.t_user_04)。
- 根据创建时间拆分,比如每个月的数据单独生成表,表的命名跟时间相关,而每年的数据又单独生成库。如:db2021.user_1。
2.2 垂直分片
- 存在一个宽表(即包含过多字段的表),其中某几个字段属于热点数据,客户端请求某一条记录,大部分情况下都是要获取这条记录中的某几个热点字段。这个时候,将这张表拆分为主表和从表两张表,热点数据单独成表(从表),这样数据访问/更新会避免在宽表上的大量操作。
- 在业务比较复杂或规模大幅度扩展时,可以把一系列的关联业务都放在少数的几个库中。如:user、order。
这时user和order两张表从同一个库拆分到不同的库中,减轻了单台机器的压力。如图:
三、不同分片使用场景和问题
3.1 垂直分片
&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;在分库分表前需要对处理的业务有充分的了解。在设计数据库时要考虑如下几个问题:
- 提前合计好对应的主从表。
- 按照不同的业务模块拆分数据库,比如用户、订单、物流、商品、字典表等分配到不同的业务组,这样可以适当的减少单个服务器的压力。
3.2 水平分片
&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;分表,将同一批数据拆分为多张表,依然在同一数据库中,可避免跨库事务的影响。但如果数据操作仍然在一个库一个服务器中,还是没有办法减轻单节点的压力。
&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;&nesp;但将数据库也进行拆分,虽然可减轻单节点的访问压力,又迎来了分布式事务的问题。