分表|分库分表是什么,为什么要分库分表?

先来看一个案例:小明是一家初创公司电商平台的开发人员,它负责卖家模块的功能开发,其中涉及了店铺、商品的相关业务,设计了如下数据库:
分表|分库分表是什么,为什么要分库分表?
文章插图
随着公司业务快速发展,数据库中的数据量猛增,访问性能也变慢了,优化迫在眉睫。分析了下问题出现在哪儿呢?关系型数据库本身比较容易成为系统瓶颈、单机存储容量、连接数、处理能力有限。当单表的数据量达到1000W或100G以后,由于查询纬度较多,及时添加从库、优化索引,做很多操作时性能仍下降严重。
方案一:
通过提升服务其硬件能力来提高数据处理能力,比如增加存储容量、cpu等,这种方案成本比较高,并且瓶颈在MySql本身,那么提高硬件也是有限的。
方案二:
通过把数据分散到不同的数据库中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。比如:将电商数据库拆分为若干独立的数据库,并且对于大表来说也拆分为若干小表,通过这种数据库拆分的方法来解决数据库的性能问题。
因此,分库分表的目的就是为了解决由于数据量过而导致数据库性能降低的问题,将原来独立的数据库拆分为若干数据库组成,将数据大表拆分成若干数据表,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
分库分表的方式
分库分表的方式在生产中通常包括:垂直分库、垂直分表、水平分库和水平分表四种。
垂直分表
还是以商品信息表为例:用户在浏览商品列表时,只有对商品感兴趣时才会点进去查看商品的详细描述信息。因此,商品信息中商品描述字段访问频率比较低,且该字段存储占用空间较大,访问单个商品IO时间较长;商品信息表中商品名称、商品图片、商品价格等其它字段数据访问频率较高。
由于这两种数据特性不一样,因此考虑将商品信息表拆分为两个小表(t_goods_01,t_goods_02),将访问频率低的商品描述信息单独存放在一张表中(t_goods_01),将访问频率高的商品基本信息单独放在另一张表中(t_goods_02)。
如下所示:
分表|分库分表是什么,为什么要分库分表?
文章插图
以上这种优化操作,就叫垂直分表。
其定义:将一个表按字段分成多表,每个表存储其中一部分字段。
带来的提升是:
为什么大字段IO效率低:
第一由于数据量本身大,需要更长的读取时间;
第二是跨页,页是数据存储单位,很多查找及定位操作都是以页为单位,单页内的数据行越来越多数据库整体性能越好,而大字段占用空间大,单页内存储行数少,因此IO效率低。
第三,数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率高,减少了磁盘IO,从而提升了数据库性能。
一般来说,某业务实体中的各个数据项的访问频率是不一样的,部分数据项可能是占用存储空间比较大的。例如商品描述。所以,当表数据量大时,可以将表按字段切开,将热门字段、冷门字段分别放一个表。
垂直分库
通过垂直分表性能得到了一定程度的提升,但是还没有达到要求,并且磁盘空间也快不够了,因为数据还是始终限制在一台服务器,库内垂直分表直接就了单一表数据量过大的问题,但没有将表分布到不同的服务器上,因此每个表还是竞争同一个物理机的CPU、内存、网络IO和磁盘。
所以,经过思考,把原有的卖家表,分为了商品库和店铺库,并把这两个库分散到不同的服务器,如下图:
分表|分库分表是什么,为什么要分库分表?
文章插图
由于商品信息与商品描述业务耦合度较高,因此一起被存放在商品库;而店铺信息相对独立,因此单独被放到店铺库。
以上这种优化就叫:垂直分库。
垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。
它的提升是:
最后,垂直分库通过将表按业务分类,然后分布不同的数据库,并且可以将这些数据库部署在不同的服务器上,从而达到多个服务器共同分摊压力的效果,但是依然没有解决单表数据量过大的问题。
水平分库
经过垂直分库后,数据库性能得到了一定程度上的解决,但是随着业务的增长,商品库单库存储数据已经超出预估。粗略估计,目前有8w个店铺,每个店铺平均150个不同规格的商品,再算上增长,商品数量得往1500w+上预估,并且商品库属于访问频率非常高的资源,单台服务器已经无法支撑。