文章目录
一、分库分表概述
1. 分库分表是什么
SELECT p.*,r.[地理区域名称],s.[店铺名称],s.[信誉]
FROM [商品信息] p
LEFT JOIN [地理区域] r ON p.[产地] = r.[地理区域编码]
LEFT JOIN [店铺信息] s ON p.id = s.[所属店铺]
WHERE p.id = ?
- 形成类似以下列表展示:
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
2. 分库分表的方式
2.1 垂直分表
垂直分表定义:将一个表按照字段分成多表,每个表存储其中一部分字段。
接下来通过一个商品查询的案例讲解垂直分表。 通常在商品列表中是不显示商品详情信息的,如下图:
由于这两种数据的特性不一样,因此考虑将商品信息表拆分如下:
1.访问频次低的商品描述信息单独存放在一张表中
2.访问频次高的商品基本信息单独放在一张表中
- 商品列表可采用以下sql:
SELECT p.*,r.[地理区域名称],s.[店铺名称],s.[信誉]
FROM [商品信息] p
LEFT JOIN [地理区域] r ON p.[产地] = r.[地理区域编码]
LEFT JOIN [店铺信息] s ON p.id = s.[所属店铺]
WHERE…ORDER BY…LIMIT…
SELECT * FROM [商品描述] WHERE [商品ID] = ?
它带来的提升是:
- 为了避免IO争抢并减少锁表的几率,查看详情的用户与商品信息浏览互不影响
- 充分发挥热门数据的操作效率,商品信息操作的高效率不会被商品描述的低效率所拖累。 一般来说,某业务实体中的各个数据项的访问频次是不一样的,部分数据项可能是占用存储空间比较大的BLOB或 是TEXT。例如上例中的商品描述。
- 所以,当表数据量很大时,可以将表按字段切开,将热门字段、冷门字段分开放在不同库中,这些库可以放在不同的存储设备上,避免IO争抢。垂直切分带来的性能提升主要集中在热门数据的操作效率上,而且磁盘争用情况减少。
通常我们按以下原则进行垂直拆分:
- 把不常用的字段单独放在一张表;
- 把text,blob等大字段拆分出来放在附表中;
- 经常组合查询的列放在一张表中;
2.2 垂直分库
由于商品信息与商品描述业务耦合度较高,因此一起被存放在PRODUCT_DB(商品库);
而店铺信息相对独立,因此 单独被存放在STORE_DB(店铺库)。
它带来的提升是:
垂直分库通过将表按业务分类,然后分布在不同数据库,并且可以将这些数据库部署在不同服务器上,从而达到多个服务器共同分摊压力的效果,但是依然没有解决单表数据量过大的问题。
2.3 水平分库
尝试水平分库,将店铺ID为单数的和店铺ID为双数的商品信息分别放在两个库中。
2.4 水平分表
按照水平分库的思路对他把PRODUCT_DB_X(商品库)内的表也可以进行水平拆分,其目的也是为了解决单表数据量大的问题,如下图:
- 与水平分库的思路类似,不过这次操作的目标是表,商品信息及商品描述被分成了两套表。
- 如果商品ID为双数,将此操作映射至商品信息1表;
- 如果商品ID为单数,将操作映射至商品信息2表。
- 此操作要访问表名称的表达式为商品信息[商品ID%2 + 1] 。(与上图中商品ID%2 原理一样)
2.5 小结
- 本章介绍了分库分表的各种方式,它们分别是垂直分表、垂直分库、水平分库和水平分表:
- 垂直分表:可以把一个宽表的字段按访问频次、是否是大字段的原则拆分为多个表,这样既能使业务清晰,还能提升部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失。
- 垂直分库:可以把多个表按业务耦合松紧归类,分别存放在不同的库,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能,同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。
- 水平分库:可以把一个表的数据(按数据行)分到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能。它不仅需要解决跨库带来的所有复杂问题,还要解决数据路由的问题(数据路由问题后边介绍)。
- 水平分表:可以把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。
- 一般来说,在系统设计阶段就应该根据业务耦合松紧来确定垂直分库,垂直分表方案,在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且持续增长,再考虑水平分库水平分表方案。
3. 分库分表带来的问题
分库分表能有效的缓解了单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数的瓶颈,同时也带来 了一些问题。
3.1 事务一致性问题
由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题。
3.2 跨节点关联查询
在没有分库前,我们检索商品时可以通过以下sql对店铺信息进行关联查询:
SELECT p.*,r.[地理区域名称],s.[店铺名称],s.[信誉]
FROM [商品信息] p
LEFT JOIN [地理区域] r ON p.[产地] = r.[地理区域编码]
LEFT JOIN [店铺信息] s ON p.id = s.[所属店铺]
WHERE…ORDER BY…LIMIT…