首页 > 数据库 >【面试】一文搞懂MySQL的分库分表!

【面试】一文搞懂MySQL的分库分表!

时间:2024-08-22 23:24:53浏览次数:9  
标签:分库 拆分 MySQL 哈希 数据量 分片 分表 搞懂

        MySQL 分库分表是一种数据库优化手段,通常用于应对数据量巨大、并发量高的场景。随着系统数据的增长,单个数据库可能难以承受高负载,进而影响性能和可扩展性。分库分表的目标是将数据分散到多个库或表中,从而减少单一库或表的压力,提高系统性能。

目录

一 我们为什么要分库分表?

二 怎么分:水平拆分与垂直拆分

三 如何进行分库分表操作

一 我们为什么要分库分表?

1.性能问题

  • 数据量过大:当单个表的数据量非常大时,查询、插入、更新等操作的性能会明显下降。MySQL 性能通常随着单表数据量的增加而下降,数百万、数千万甚至更大的数据量可能导致响应时间变慢。
  • 并发读写压力:当大量用户同时进行读写操作时,单个数据库实例可能承受不了高并发,造成数据库瓶颈和宕机风险。

2.扩展性问题

  • 存储瓶颈:数据库存储有上限,不可能无限扩展单个数据库实例的存储容量。如果数据量增长到单个数据库服务器难以承载的规模,就需要对数据进行切分。
  • 数据库维护成本高:随着数据量和并发的增加,备份、恢复、迁移等运维工作会变得越来越困难和耗时。

3.业务需求

        当业务快速发展,数据量和用户量急剧增加时,使用分库分表可以保证系统的扩展性和高可用性。

二 怎么分:水平拆分与垂直拆分

1. 垂直拆分(竖着分)

        垂直拆分是基于表的字段进行拆分,将一个表中的不同列拆分到不同的库或表中,通常用于优化查询效率、减少数据冗余。

        分表之后,每个表的结构、数据都不一样,所有表的数据构成了原始数据集。通常表与表之间会存在至少一个关联字段,用于连接多表。

        适用场景:

        当表的列非常多时(上百列),部分列经常被使用,而其他列很少被访问。这时将常用的列和不常用的列分开存储,能够提高查询效率,减少数据冗余和磁盘 I/O。

        表中的一些列较大且少用(如大字段、大文本、Blob 字段等),可以将这些字段独立出来存储,避免影响经常使用的字段的查询性能。

        例如对于一个用户表 user,包含用户的基本信息(如 id、name、email 等)和扩展信息(如详细地址、头像、个人简介等),可以将用户的基本信息和扩展信息分到不同的表中。

user_basic(id, name, email)        -- 常用字段
user_extra(id, address, avatar, bio) -- 不常用字段

        垂直拆分可以减少表的宽度,也就是减少每次查询时扫描的字段,提升查询效率,同时将不同业务模块分开,便于开发和维护。

         但是垂直拆分后需要额外的维护成本,如拆分后需要处理关联查询,增加开发复杂度;拆分后可能依然无法解决单表行数过大的问题,仍需要水平拆分来进一步优化。

2.水平拆分(横着分)

        水平拆分是基于表的行进行拆分,将同一个表中的不同数据分布到不同的库或表中。常用于解决单表数据量过大、查询和写入性能问题。

        拆分后,每个表的结构是一样的,但是数据独立,均不一样,没有交集,所有表的数据共同构成了全部原始数据。

        适用场景:

        当单个表中的数据量非常大,导致查询、写入性能下降时。水平拆分能将数据分布到多个表或库中,减轻单表的负担。

        适合业务规模扩展较大、用户群体广泛的数据处理场景,如电商、社交平台等。

        例如有一个订单表 order,每天有成千上万条订单记录,可以根据订单号、用户 ID、时间等字段对表进行水平拆分。

order_2021(id, user_id, order_amount, order_date)
order_2022(id, user_id, order_amount, order_date)

        MySQL水平拆分通常使用的数据分片策略有两种:

        1)范围分片:按时间、ID范围等,将数据切分到不同表或库中。

        2)哈希分片:通过对某个字段(如用户 ID 或订单 ID)取哈希值,将数据均匀地分布到多个表或库中。

        水平分片有利于分散数据压力,解决单表数据量过大、查询速度慢的问题,提升数据库的性能,而且可以根据业务规模的变化,逐渐增加新的分库或分表来扩展系统的容量,具有很强的扩展性。但是开发和运维的复杂性增加,因为当进行查询和插入操作时,需要额外逻辑判断该访问哪个库或表,而且会涉及分布式事务。

三 如何进行分库分表操作

1.判断是横向拆分还是纵向拆分

        如果某些字段比较独立且较少被访问,或者表的字段特别多(几十甚至上百个),且访问时经常只需要部分字段,可以考虑垂直拆分。

        如果表的行数非常大,影响了查询和写入性能,或者业务需求导致数据量增长迅速,预计将来会超过单表或单库的处理能力,可以考虑水平拆分。

2.拆分数量的判断

        我们可以根据业务逻辑的模块、字段的访问频率等进行拆分,经常访问的字段可以保留在一个表中,较少访问或大字段(如图片、文档)可以独立拆分出去。

        水平拆分可以根据表的数量进行预测,例如,如果预计未来数据量为 1 亿条,单表容量限制为 1000 万,则需要拆分为 10 个表。或者结合系统并发量、服务器容量和架构而定。

3.如何实现均匀拆分

        哈希取模:根据某个字段(如用户 ID、订单 ID)取哈希值,然后对拆分表的数量取模,将数据分布到不同表或库中。哈希取模是一种非常常用的分片策略,能够确保数据均匀分布。

        范围分片:根据某个字段的值范围进行划分,将数据分布到不同表中。例如根据订单日期进行分片。

        一致性哈希:使用一致性哈希算法来分配数据,可以动态增加或减少节点(表或库),并且能保证数据分布均匀,适用于分布式系统中。

        选择合理的分片键:分片键应当是查询时常用的字段,并且其值的分布要尽量均匀。避免选择高度聚集的字段(如创建时间、递增 ID 等),否则会导致数据倾斜。

        避免热点:在某些情况下,特定的数据可能会成为访问热点,导致部分表或库的访问频率过高。为了避免这种情况,可以使用合理的分片策略(如哈希分片)来均衡负载。

        动态扩容:当数据量持续增长,可以考虑通过增加分片表的数量来进行扩容。为了避免在扩容过程中发生数据倾斜,可以采用一致性哈希等动态分片算法。

标签:分库,拆分,MySQL,哈希,数据量,分片,分表,搞懂
From: https://blog.csdn.net/Liu_y_xin/article/details/141439971

相关文章

  • MySQL面试问题(二)
    MySQL面试问题(二)文章目录MySQL面试问题(二)为什么要使用索引索引是不是越多越好MySQL索引机制什么是聚簇索引没有主键innodb如何处理联合索引批量向MySQL中导入1000w数据如何优化分页时偏移量很大效率很差如何优化大数据量高并发访问数据库优化方法为什么要使用索引......
  • [Mysql]执行一条语句的过程
    执行一条select语句,期间发生了什么?学习SQL的时候,大家肯定第一个先学到的就是select查询语句了,比如下面这句查询语句://在product表中,查询id=1的记录select*fromproductwhereid=1;但是有没有想过,MySQL执行一条select查询语句,在MySQL中期间发生了什么?......
  • MySql中常用的sql语句大全(工作常用篇)
    1.DDL1.1操作数据库--创建库createdatabase库名;--创建库时判断库是否存在,不存在则创建createdatabaseifnoexists库名;--查看所有数据库showdatabases;--使用指定数据库use库名;--查看当前指定数据库包含的数据表showtables;--查看数据库的结......
  • 如何避免Mysql RR 隔离级别下的 INSERT 死锁
    背景       我们公司架构师,在使用Mysql做分布式锁的时候,因insert唯一键冲突,造成死锁。引起我对这部分知识点的兴趣和研究。       死锁日志的详细信息如下:LATESTDETECTEDDEADLOCK------------------------2024-08-1916:32:450x7f92b0ca2700***......
  • MySQL高可用方案
    1.https://vitess.io/zh/2.orchestrator主从方案基于二进制日志文件和位置的复制原理:从服务器根据主服务器的二进制日志(binlog)中的文件名和位置进行复制。配置:在从服务器上配置主服务器的binlog文件名和位置。故障转移:手动介入:一旦主服务器故障,需要手动重新配置新的主服......
  • Mysql
    1、时间差(秒级别)selectcreatime,updatime,TIMESTAMPDIFF(MICROSECOND,creatime,updatime)/1000000  AS time_diff  from  表名whereapplicationlike'%17%'and creatime>"2024-06-1414:41:29.803"andclient_idin("LSW12345678901223") ......
  • Pycharm连接mysql数据库
    importpymysql1、需要使用pymysql在三方库;importpymysqlconfig={'user':'investbank_newforp','password':'m@H2wp4B@7e9','host':'192.168.154.241','port':15213,......
  • 安装MySQL报错ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost:3
    今天要在本地装个mysql,发现mysql-5.7.19-winx64版总是报错由于找不到MSVCP120.dll,无法继续执行代码。重新安装程序可能会解决此问题。,去微软官网找到了最新的VisualC++RedistributableforVisualStudio,下载后发现还是不停地报错。怀疑是系统不兼容,没办法只好安装mysql-8.0.37......
  • MySQL 数据类型详解
    MySQL是一种广泛使用的关系型数据库管理系统,它支持多种数据类型以满足各种应用场景的需求。本文将详细介绍MySQL支持的数据类型、它们的使用场景以及实现原理,并通过图示帮助读者更直观地理解。目录简介数值类型整型浮点型定点型日期和时间类型字符串类型字符串二进制字......
  • mysql57小版本升级操作指南
    1.关停注意要使用慢速关闭mysql,这样InnoDB在关闭之前执行完整的清除和更改缓冲区合并。登录到mysql中执行mysql>SETGLOBALinnodb_fast_shutdown=0;mysql>shutdown; 2.备份注:备份数据目录和应用程序,注意mysql的属主属组数据目录查找方式:MySQL的数据目录通常由......