vlambda博客
学习文章列表

数据库分库分表--前奏篇


数据库和表的演变

单库单表

项目前期基本都是单库单表,单库单表也是最常见的数据库设计,比如说:有一张用户表User,被放到数据库中,所有的用户的信息都被存储在该数据库的这张User表里。

单库多表

随着用户量的增加,User表的数据越来越多,一旦当数据量达到一定量的时候,对User表的查询会变得越来越慢,从而渐渐的影响整个数据的性能。有时候可能涉及到需要对User表添加一列,如果Mysql版本较低的话,这时候Mysql会锁表,会导致所有的读写操作只能等待添加操作完毕。

这时候可以通过某种机制或者规则将表里的数据进行拆分。比如说:user_id是0到10000的放到User_01表里,将user_id是10001到20000的用户信息放到User_02表里,......。这些表组合起来就是一个系统完整用户信息。

多库多表

随着用户数据量的不断增加,单台数据库的存储空间也许就不够用了,并且随着查询量的不断增加,单台数据库的服务已经没法支撑这些查询了,因为表的数据量太大,所以在增加和减少索引时需要消耗很长时间。这时候可以针对User_01,User_02,....User_10放到一个数据库里,User_11,User_12,...User_20放到一个数据库里.....这样就之前的一个数据库,拆分成了n多个数据库。这时候表和数据库就从单表单库到了多表多库了。

何为分开分表

由于用户数据量不断的增加,我们怎样存储这些数据呢?要怎样才能让系统不会因此而受到影响呢?

目前,数据拆分是这两个问题的主流解决方案。最终目的就是讲用户数据进行分而治之,在数据库存储方面是通过对数据库和表进行分库分表来实现,对数据的拆分主要有两种手段:垂直拆分和水平拆分

垂直拆分

根据业务的维度,将原本的一个库或者表拆分成多个库或者表,每个库或者表的结构和原来的结构有所不同。

比如说:之前的数据库里除了用户的信息表User以外,可能还有交易表等。而现在按照垂直拆分后,用户信息放在一个库,交易信息放一个库。

水平拆分

根据分片算法,将一个数据或者表拆分成多个库或者多个表,每个库和表保留着原来的结构。

比如说:一个库拆分成多个库后,每个库里也是有用户的信息表、交易表的结构都是一样的,只是数据存的不一样了。

上面的两种拆分方法可能也会在一个系统里同时存在,在互联网应用的开发过程中,通常先进行垂直拆分,是单体应用变成多个微服务结构,在微服务中在进行水平拆分库或者表。

在什么情况下需要咱们进行分库分表呢

首先,如果在一个库中的表数据超过了一定的数量,可以理解为阈值。比如说:在Mysql的表中达到千万级别数据就需要考虑分库分表(这个千万也是相对的,和你的表设计还是有些关系的),这样,数据就被分散在不同的表上,单表的索引大小得到控制,会提升查询性能的,对索引以及表结构的变更会更加方便和高效的。当数据库实例的吞吐量达到性能瓶颈的时候,我们需要扩展数据库实例,让每个数据库实例承担其中一部分数据库的请求,分解大量请求带来的整体压力。

现在,大多数数据库实例都可以创建多个数据库,那么为什么在分库分表中要创建多数据库呢?因为如果扩容时候有多个数据库,则只要通过DBA的操作,就可以将不同的数据库移动到不同的数据库实例中,在应用层不用对数据和表的配置进行变更,只需要增加对实例的引用。

下面总结一下在什么情况下需要分库分表?

  1. 如果在数据库中的表中的数据量达到一定程度或者是阈值,则需要进行分库分表,分解单表的大数据量对索引查询带来的压力,并方便对索引和表结构进行变更。

  2. 如果数据库的吞吐量达到瓶颈了,就需要增加数据库实例,利用多个数据库实例来分解大量的数据请求带来的系统压力。

  3. 如果希望在扩容时候对应用层的配置改变最少,就需要在每个数据实例中预留足够的数据库数量。