MySQL之分库分表

本文探讨了在高并发场景下,通过分库分表提高数据库性能的必要性和策略。详细介绍了分库分表的概念、迁移过程以及分库分表后全局ID的生成方法,包括数据库自增ID、UUID、系统当前时间戳和SnowFlask等方案的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 为什么要分库分表?

       倘若我们没有进行分库分表,那么整个架构图如下所示:

在这里插入图片描述

       可以看到,多个系统的实例都在访问同一个MySQL实例,随着业务量的增加,我们可以在增加系统的实例,但是始终访问的都是同一个实例。并且,如果每一个系统实例的读写请求都特别高,一个MySQL实例也是顶不住过多的请求,便造成数据库的宕机,整个系统无法服务。

       而如果进行分库分表之后,架构图如下所示:

在这里插入图片描述

       可以看到,原本的读写请求由一台MySQL实例,现在由三台MySQL实例承担。不仅提高了读写请求的承担能力,同时,数据也可以被接近于平均分配到每台MySQL实例中,这样数据查询速度也提高了。

2. 分库分表

       首先需要知道的是,分库、分表是两个不同的概念。

       分库指的是将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。多台MySQL的实例中,每个实例中都有一摸一样的表,除了表中的数据。

       分表指的是把一个表的数据放到多个表中,然后查询的时候你就查一个表。同时,分表又分为水平切分和垂直切分。

       水平拆分的意思,就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。水平拆分的意义,就是将数据均匀放更多的库里,然后用多个库来抗更高的并发,还有就是用多个库的存储容量来进行扩容。

在这里插入图片描述

       垂直拆分的意思,就是把一个有很多字段的表给拆分成多个表,或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会将较少的访问频率很高的字段放到一个表里去,然后将较多的访问频率很低的字段放到另外一个表里去。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。

在这里插入图片描述

3. 如何把系统迁移到分库分表

       倘若我们的系统之前采用单台MySQL实例的方案,现在要将其进行分库分表,那么表中的数据应该如何进行迁移,同时不能对用户造成干扰。

在这里插入图片描述
       迁移过程如上图所示,后台将数据迁移完成后,替换掉之前读写旧数据库的代码即可。

4. 分库分表后全局 id 如何生成

       在单实例的情况下,我们通常都是采用自增主键的方式进行 id 的生成,这样做到好处是,数据 id 向增大的方向生成,可以避免随机生成带来数据页的频繁裂化,降低MySQL的效率。

       如果我们根据id对数据进行分库分表,如果每张表依然开启主键自增,显然是不够合适的。每张表中可能会出现id相同的数据,这样情况显然是不被允许的。

       之前在实习的过程中,是这样做到,调用一个RPC的方法,专门用于生成全局唯id

       现在让我们研究一下全局id应如何生成。

4.1 数据库自增 id

       这里的数据库自增 id ,并不是指开启分库分表的自增。而是单独搞一张表,用于生成id。每次有新的数据插入,都访问这张表,获取自增后的id,作为分库分表后的数据id,如此便一定能保证全局唯一id

create table t_generateId(
	id bigint primary key auto_increment 
);

在这里插入图片描述

       该方案适用于并发量很低的情况,我们做分库分表,就表明并发量较高了。如果生成id的这台MySQL实例不能顶得住过多的写请求,很容易造成整个系统的宕机。

4.2 uuid

       前面说了,选择主键时,通常会让其向一个方向进行增长,这样可以避免数据页的频繁裂化及合并。

       而uuid增完全是随机的,很容易造成上述情况,所以并不推荐使用。

       其主要用于设置文件名,如我们QQ截图时,可以用uuid作为截图后的文件名。

4.3 系统当前时间戳

       时间戳比uuid的好处时,其数据是朝一个方向进行增长的。到那时如果并发量很高的时候,同一时刻有多个请求,显然是不合适的。

       适合的场景:一般如果用这个方案,是将当前时间跟很多其他的业务字段拼接起来,作为一个id,如果业务上你觉得可以接受,那么也是可以的。你可以将别的业务字段值跟当前时间拼接起来,组成一个全局唯一的编号,订单编号,时间戳 + 用户id + 业务含义编码。

4.4 SnowFlask

       SnowFlask

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值