加入收藏 | 设为首页 | 会员中心 | 我要投稿 淮北站长网 (https://www.0561zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql分库分表分页查询语句_Mysql分库分表方案

发布时间:2022-12-03 08:03:39 所属栏目:MySql教程 来源:未知
导读:
为什么要分表
当一张表的数据达到几千万时,你查询一次所花的时间会变多MySQL分页查询,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。

0586fa059cd0d6b061b5d578c5ec8eb0.png

为什么要分表

当一张表的数据达到几千万时,你查询一次所花的时间会变多MySQL分页查询,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。那么为什么会很慢呢?

1、Mysql使用的文件存储系统问题,例如Ext3文件系统对大于大文件处理上就有许多问题(例如容纳的文件大小、子目录存储及每个数据块的大小4K的限制),当然可以采取XFS文件系统来解决;

2、表数据太大,导致后续的数据表结构调整相关操作很不方便;

3、从Innodb本身来讲数据文件的Btree上只有两个锁, 叶子节点锁和子节点锁,可以想而知道,当发生页拆分或是添加新叶时都会造成表里不能写入数据。

解决方案 利用merge存储引擎

如果要把已有的大数据量表分开比较痛苦,最痛苦的事就是改代码,因为程序里面的sql语句已经写好了。用merge存储引擎来实现分表, 这种方法比较适合.

举例子:

c410f12f7395a4afe3813bd247dbb4ba.png

主从复制

MySQL的主从复制解决了数据库的读写分离,并很好的提升了读的性能,其图如下:

03a1c613c921e3273a416a2bea5c3957.png

其主从复制的过程如下图所示:

706794f4fffe46529d7bc8b50585e86d.png

但是,主从复制也带来其他一系列性能瓶颈问题:

1、写入无法扩展

2、写入无法缓存

3、复制延时

4、锁表率上升

5、表变大,缓存率下降

分库分表

垂直切分

如果把业务切割得足够独立,那把不同业务的数据放到不同的数据库服务器将是一个不错的方案,而且万一其中一个业务崩溃了也不会影响其他业务的正常进行,并且也起到了负载分流的作用,大大提升了数据库的吞吐能力。经过垂直分区后的数据库架构图如下:

ac1966c8834c69ddbe401b696e43914b.png

然而,尽管业务之间已经足够独立了,但是有些业务之间或多或少总会有点联系,如用户,基本上都会和每个业务相关联,况且这种分区方式,也不能解决单张表数据量暴涨的问题,因此为何不试试水平分割呢?

水平分片(Sharding)

这是一个非常好的思路,将用户按一定规则(按id哈希)分组,并把该组用户的数据存储到一个数据库分片中,即一个sharding,这样随着用户数量的增加,只要简单地配置一台服务器即可,原理图如下:

e93bf7a61286bce09da64cc5f3015d80.png

如何来确定某个用户所在的shard呢,可以建一张用户和shard对应的数据表,每次请求先从这张表找用户的shard id,再从对应shard中查询相关数据,如下图所示:

516890a49f1779b10ec6281e8de28e07.png

基本原则

单库单表

单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到。

单库多表

随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能。如果使用mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有的读写操作只能等待。

可以通过某种方式将user进行水平的切分,产生两个表结构完全一样的user_0000,user_0001等表,user_0000 + user_0001 + …的数据刚好是一份完整的数据。

多库多表

随着数据量增加也许单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。这个时候可以再对数据库进行水平区分。

分库分表规则

设计表的时候需要确定此表按照什么样的规则进行分库分表。例如,当有新用户时,程序得确定将此用户信息添加到哪个表中;同理,当登录的时候我们得通过用户的账号找到数据库中对应的记录,所有的这些都需要按照某一规则进行。

路由

通过分库分表规则查找到对应的表和库的过程。如分库分表的规则是user_id mod 4的方式,当用户新注册了一个账号,账号id的123,我们可以通过id mod 4的方式确定此账号应该保存到User_0003表中。当用户123登录的时候,我们通过123 mod 4后确定记录在User_0003中。

分库分表维度的问题

假如用户购买了商品,需要将交易记录保存起来,如果按照用户的纬度分表,则每个用户的交易记录都保存在同一表中,所以很快很方便的查找到某用户的 购买情况,但是某商品被购买的情况则很有可能分布在多张表中,查找起来比较麻烦。反之,按照商品维度分表,可以很方便的查找到此商品的购买情况,但要查找 到买人的交易记录比较麻烦。

所以常见的解决方式有:

联合查询的问题

联合查询基本不可能,因为关联的表有可能不在同一数据库中。

避免跨库事务

避免在一个事务中修改db0中的表的时候同时修改db1中的表,一个是操作起来更复杂,效率也会有一定影响。

尽量把同一组数据放到同一DB服务器上

例如将卖家a的商品和交易信息都放到db0中,当db1挂了的时候,卖家a相关的东西可以正常使用。也就是说避免数据库中的数据依赖另一数据库中的数据。

那么分库分表多少合适呢?

经测试在单表1000万条记录一下,写入读取性能是比较好的. 这样在留点buffer,那么单表全是数据字型的保持在800万条记录以下, 有字符型的单表保持在500万以下。

如果按 100库100表来规划,如用户业务:

500万*100*100 = 50000000万 = 5000亿记录。

7d569c10da3893a64197978545394d5e.png

欢迎移步搜索关注公众号:互联网架构师之路(hlw_architector),获取最新架构材料。

Mysql分库分表方案?mp.weixin.qq.com

813c125038addcb36f53229382d6486a.png

(编辑:淮北站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!