mysql分表分库的应用场景和设计方式
作者:laozhang 发布时间:2024-01-22 05:49:39
很多朋友在论坛和留言区域问mysql在什么情况下才需要进行分库分表,以及采用何种设计方式才是最优的选择,根据这些问题,小编为大家整理了关于MySQL分库分表的应用场景和最优的设计方式举例。
一. 分表
场景:对于大型的互联网应用来说,数据库单表的记录行数可能达到千万级甚至是亿级,并且数据库面临着极高的并发访问。采用Master-Slave复制模式的MySQL架构,
只能够对数据库的读进行扩展,而对数据库的写入操作还是集中在Master上,并且单个Master挂载的Slave也不可能无限制多,Slave的数量受到Master能力和负载的限制。
因此,需要对数据库的吞吐能力进行进一步的扩展,以满足高并发访问与海量数据存储的需要!
对于访问极为频繁且数据量巨大的单表来说,我们首先要做的就是减少单表的记录条数,以便减少数据查询所需要的时间,提高数据库的吞吐,这就是所谓的分表!
在分表之前,首先需要选择适当的分表策略,使得数据能够较为均衡地分不到多张表中,并且不影响正常的查询!
对于互联网企业来说,大部分数据都是与用户关联的,因此,用户id是最常用的分表字段。因为大部分查询都需要带上用户id,这样既不影响查询,又能够使数据较为均衡地
分布到各个表中(当然,有的场景也可能会出现冷热数据分布不均衡的情况),如下图:
假设有一张表记录用户购买信息的订单表order,由于order表记录条数太多,将被拆分成256张表。
拆分的记录根据user_id%256取得对应的表进行存储,前台应用则根据对应的user_id%256,找到对应订单存储的表进行访问。
这样一来,user_id便成为一个必需的查询条件,否则将会由于无法定位数据存储的表而无法对数据进行访问。
注:拆分后表的数量一般为2的n次方,就是上面拆分成256张表的由来!
假设order表结构如下:
create table order_(
order_id bigint(20) primary key auto_increment,
user_id bigint(20),
user_nick varchar(50),
auction_id bigint(20),
auction_title bigint(20),
price bigint(20),
auction_cat varchar(200),
seller_id bigint(20),
seller_nick varchar(50)
)
那么分表以后,假设user_id = 257,并且auction_id = 100,需要根据auction_id来查询对应的订单信息,则对应的SQL语句如下:
select * from order_1 where user_id=257 and auction_id = 100;
其中,order_1是根据257%256计算得出,表示分表之后的第一张order表。
二. 分库
场景:分表能够解决单表数据量过大带来的查询效率下降的问题,但是,却无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库master
服务器无法承载写操作压力时,不管如何扩展slave服务器,此时都没有意义了。
因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库写入能力,这就是所谓的分库!
与分表策略相似,分库可以采用通过一个关键字取模的方式,来对数据访问进行路由,如下图所示:
还是之前的订单表,假设user_id 字段的值为258,将原有的单库分为256个库,那么应用程序对数据库的访问请求将被路由到第二个库(258%256 = 2)。
三. 分库分表
场景:有时数据库可能既面临着高并发访问的压力,又需要面对海量数据的存储问题,这时需要对数据库既采用分表策略,又采用分库策略,以便同时扩展系统的
并发处理能力,以及提升单表的查询性能,这就是所谓的分库分表。
分库分表的策略比前面的仅分库或者仅分表的策略要更为复杂,一种分库分表的路由策略如下:
1. 中间变量 = user_id % (分库数量 * 每个库的表数量)
2. 库 = 取整数 (中间变量 / 每个库的表数量)
3. 表 = 中间变量 % 每个库的表数量
同样采用user_id作为路由字段,首先使用user_id 对库数量*每个库表的数量取模,得到一个中间变量;然后使用中间变量除以每个库表的数量,取整,便得到
对应的库;而中间变量对每个库表的数量取模,即得到对应的表。
分库分表策略详细过程如下:
假设将原来的单库单表order拆分成256个库,每个库包含1024个表,那么按照前面所提到的路由策略,对于user_id=262145 的访问,路由的计算过程如下:
1. 中间变量 = 262145 % (256 * 1024) = 1
2. 库 = 取整 (1/1024) = 0
3. 表 = 1 % 1024 = 1
这就意味着,对于user_id=262145 的订单记录的查询和修改,将被路由到第0个库的第1个order_1表中执行!!!


猜你喜欢
- 一、ZeroMQ概述 ZeroMQ(又名ØMQ,MQ,或zmq)像一个可嵌入的网络库,但其作用就像一个并发框
- PDO是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么 php
- 不得不承认,傲游在用户体验方面是做得比较好的,所以它的用户群非常大。也正因为如此,它的某些不好的特性也造成了开发人员不可忽略的浏览器兼容问题
- 个人开发的 flask 论坛进入尾声,还剩最后一个上传图片更换头像功能,搞了一整天,最后终于解决了所有问题,现在记录下解决方案。1. 上传文
- 训练keras时遇到了一个问题,就是内存不足,将 .fit 改成 .fit_generator以后还是放不下一张图(我的图片是8192×81
- <?php/*======================================事务处理==================
- 需求:前端获取到摄像头信息,通过模型来进行判断人像是否在镜头中,镜头是否有被遮挡。实现步骤:1、通过video标签来展示摄像头中的内容2、通
- python打印当前文件的绝对路径并解决打印为空获取当前文件所在路径主要使用os.path.dirname(os.path.abspath(
- 当使用pytorch写网络结构的时候,本人发现在卷积层与第一个全连接层的全连接层的input_features不知道该写多少?一开始本人的做
- (一)问题遗传算法求解正方形拼图游戏(二)代码#!/usr/bin/env python# -*- coding: utf-8 -*-fro
- 区块链比特币从诞生到现在已经10年了,最近接触到了区块链相关的技术,为了揭开其背后的神秘面纱,我就从头开始构建一个简单的区块链。从技术上来看
- Python自带的pdb库,发现用pdb来调试程序还是很方便的,当然了,什么远程调试,多线程之类,pdb是搞不定的。用pdb调试有多种方式可
- 前言这部分已经折腾我两天了,还是没有头绪,可能还会折腾更久,最后在第三天上午解决问题,在一个不起眼的地方被坑了,jQuery加载的问题。会者
- 如下所示:import jsonresult = response.read()result.decode('utf-8')
- VScode查看python f.write()的文件乱码在使用 VScode 编写 python 代码,print(),汉字正常显示,使用
- 在logging中,Logger's level 的默认等级为warning所以虽然在handler中setlervel了,Logg
- 为什么要使用滤波消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 7 - Set and Get Style Pro
- 简介观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个
- For 循环可以遍历字符串,也可以遍历列表# for 循环# 语法特点:遍历操作,依次取集合容器中的几个值# for 临时变量