首页 教程 服务器/数据库 MySQL 的分库分表

MySQL 的分库分表

    • 分库
      • 解决什么问题:
      • 如何做?
        • 水平分库
        • 垂直分库
    • 分表
      • 解决什么问题
        • 如何做
        • 水平分表
        • 垂直分表
    • 常见的数据分片的方式(水平拆分)
        • 1. 按数据范围分片:
        • 2. 哈希取模
          • 一致性哈希(虚拟节点):redis 的集群化方案:
          • MongoDB 是怎么实现数据分片的
            • Mongo 是如何保证数据均衡的?
      • 分库分表的问题(分库分表带来的问题)
        • 1. 数据不均衡
        • 2 跨库事务
        • 3 唯一键
        • 4. 跨库查询
        • 5. 热点问题

分库

  • 将一个数据库拆分成多个数据库

解决什么问题:

  • MySQL实例分配的磁盘有限,
    • 单库的存储容量有限。如果一个库存储的数据量超出单机磁盘或文件系统的承载上限(如 ext4 的单文件 2TB 限制),超过会写入失败(我没试过,你们可以试试)
  • 单 MySQL 连接上限的问题(最大 1万多,一般最多设置 5-6k)
  • 其他
    • 性能严重下降(就像手机空间小了容易卡顿,可能是磁盘拿来当内存使(扩容);数据量大,加载的数量多,磁盘 io 增加,变慢)
    • 容易崩溃(卡死)
    • 备份与恢复漫长

如何做?

水平分库
  • 分摊数据量: 将数据库中的数据分摊到多个库
垂直分库
  • 将数据库根据业务进行拆分
  • 不同业务使用的表放到不同的数据库中
  • 比如(用户库存放用户信息,商品库,订单库)他们对应不同的功能.
  • 这样 1 可以分摊请求压力,2 可以做隔离

分表

解决什么问题

  1. 查询性能低(主要是全表扫描)
  2. 写入性能低(b+树的平衡机制)

1000 万与两亿数据读写对比

  • 全表扫描查询一条数据
    • 1000 万耗时 2s;
    • 两亿:耗时 40s
  • 写 10 万条数据耗时
    • 1000 万 2-3 秒
    • 两亿: 20-30 秒

一个查询执行太久会导致有大量的连接被占用,达到连接上限就会报错.

如何做
水平分表
  • 让一个数据表的数据行数变少,查询时间变快
垂直分表
  • 让每行数据所占空间变少,减少 io 的次数(MySQL 一次 io16k)
  • 根据不同字段的功能特点进行分表
  • 比如: 用户表有 50 个字段,可以根据信息的特点分成基本信息与拓展信息
  • 这样可以减少查询的磁盘 io 次数,降低查询耗时.

常见的数据分片的方式(水平拆分)

1. 按数据范围分片:

a. 比如一共 2亿数据(序号(id)1-2 亿),分成两个表; 序号(id)1-1 亿的数据在一个表,序号 1 亿-2 亿的在一个表
ⅰ. 缺点:数据不均
1. 假如只有1 亿零 1 条数据,按照这个分库的方法,那么第一个库有一亿数据量,另一个只有一条数据
ⅱ. 无法实现数据的动态分配

2. 哈希取模

ⅰ. 比如: 一共有 5 台服务器(实例):根据用户的 id(或者其他字段哈希成 int)%5(实例的数量)=对应的数据库 1. 优点: 解决了数据动态分配的问题 2. 缺点: 3. 容易造成数据不均衡(比如大部分的数据都在其中的一两个节点) 4. 拓展性差: 如果要增加或者减少实例的数量,需要重新配置,加载实例

一致性哈希(虚拟节点):redis 的集群化方案:

ⅰ. 固定哈希环(2^16)16384 个槽位 ⅱ. 每个节点均匀的分布在哈希环上面 ⅲ. (假设一共 10000 个大小的哈希环(其实不止),一共部署 5 个实例,哈希值在 0-2000 的数据储存到节点 1;2000 到 4000 的数据储存在节点 2; 以此类推,占满 整个哈希环 1. 问题(数据不均衡):数据的哈希值90% 都哈希再 0-2000 ,那么 90% 的数据储存在第一个哈希环,造成严重的数据不均衡 2. 解决方案:虚拟节点 a. 90% 的数据都哈希再 0-2000 的范围内,那么把 0-2000 的数据进行拆分,按 400一格分成 5 格,那么就可以插入 4 个虚拟节点 , b. 虚拟节点并不是真正的,而是拦截数据将其转移到真正的节点上 ⅰ. 比如 400 处有一个节点指向 4000 的真实节点(槽),那么哈希值 0-400 的数据将被虚拟节点拦截,并储存到真实节点4000中,解决节点负载不均的问题

b. 优点:
ⅰ. 解决数据动态分配,数据均匀分表,实例拓展问题

MongoDB 是怎么实现数据分片的

a. 主要是三种分片方案
ⅰ. 范围
ⅱ. 哈希
ⅲ. 标签(按照不同的标签将数据放到不同的实例)

Mongo 是如何保证数据均衡的?

■ Chunk(数据块): 数据在每个分片上的基本单位。每个 Chunk 包含一段连续的范围数据(基于分片键)。 ■ Balance(均衡): 是 MongoDB 自动调整数据分布的过程,即通过迁移 Chunk 来保持分片之间的均衡。 ■ Chunk 的拆分 ● 一个块最大 64MB,超过最大值就自动分成两个块,没有数据的迁移,很快 ■ 数据均衡的一个重要组成部分是 Chunk 的迁移。MongoDB 会根据数据量和负载情况定期移动 Chunk,确保所有分片的存储容量保持平衡。 ● 过程

当某个分片的 Chunk 数据量过大或某些分片的数据量较小,MongoDB 会通过均衡器(Balancer)将 Chunk 从一个分片迁移到另一个分片。
迁移是自动进行的,MongoDB 会确保迁移过程中数据的完整性和一致性。
迁移操作会在后台执行,尽量减少对客户端请求的影响。

优点: 数据的均衡与负载均衡
缺点: 是内部线程实现的,有一定的性能消耗

分库分表的问题(分库分表带来的问题)

1. 数据不均衡
  • 比如两个数据库,取余大部分数据(80%)都是一个数据库中的怎么办?
2 跨库事务

分库后,数据可能分布在不同的库中。例如:

一个订单系统,订单信息和用户信息被拆分到不同的库。如果需要在一个事务中同时更新订单状态和用户余额,就涉及跨库事务。

3 唯一键

对表/库进行水平拆分后就无法保持强唯一约束了

  • 解决方案
  1. UUID:

使用 UUID 生成唯一标识。
优点:保证全局唯一;缺点:UUID 长度大,索引性能较差。

  1. 雪花算法:

基于时间戳生成全局唯一 ID(如 Twitter 的 Snowflake 算法)。
优点:高效,生成的 ID 有序;缺点:依赖外部服务。

  1. 数据库自增步长:

设置每个库的自增 ID 起始值和步长。例如:
库1:1, 3, 5…
库2:2, 4, 6…
优点:实现简单;缺点:不适用于动态扩容。

4. 跨库查询

问题
分库后,复杂查询(如多表 JOIN 或聚合操作)变得困难。例如:

查询某用户的所有订单和支付记录,但订单和支付信息在不同库中。

5. 热点问题

分库分表可能导致数据访问集中于某些分片。例如:

用户按 ID 分片,但某些大客户的操作频繁集中到一个库,造成热点

参考:
https://cloud.tencent.com/developer/article/1901963
https://www.cnblogs.com/chengxy-nds/p/16924305.html
https://cloud.tencent.com/developer/article/1843987

评论(0)条

提示:请勿发布广告垃圾评论,否则封号处理!!

    猜你喜欢
    【MySQL】用户管理

    【MySQL】用户管理

     服务器/数据库  2个月前  2.18k

    我们推荐使用普通用户对数据的访问。而root作为管理员可以对普通用户对应的权限进行设置和管理。如给张三和李四这样的普通用户权限设定后。就只能操作给你权限的库了。

    Cursor Rules 让开发效率变成10倍速

    Cursor Rules 让开发效率变成10倍速

     服务器/数据库  2个月前  1.24k

    在AI与编程的交汇点上,awesome-cursorrules项目犹如一座灯塔,指引着开发者们驶向更高效、更智能的编程未来。无论你是经验丰富的老手,还是刚入行的新人,这个项目都能为你的编程之旅增添一抹亮色。这些规则文件就像是你私人定制的AI助手,能够根据你的项目需求和个人偏好,精确地调教AI的行为。突然间,你会发现AI不仅能理解Next.js的最佳实践,还能自动应用TypeScript的类型检查,甚至主动提供Tailwind CSS的类名建议。探索新的应用场景,推动AI辅助编程的边界。

    探索Django 5: 从零开始,打造你的第一个Web应用

    探索Django 5: 从零开始,打造你的第一个Web应用

     服务器/数据库  2个月前  1.16k

    Django 是一个开放源代码的 Web 应用程序框架,由 Python 写成。它遵循 MVT(Model-View-Template)的设计模式,旨在帮助开发者高效地构建复杂且功能丰富的 Web 应用程序。随着每个版本的升级,Django 不断演变,提供更多功能和改进,让开发变得更加便捷。《Django 5 Web应用开发实战》集Django架站基础、项目实践、开发经验于一体,是一本从零基础到精通Django Web企业级开发技术的实战指南《Django 5 Web应用开发实战》内容以。

    MySQL 的mysql_secure_installation安全脚本执行过程介绍

    MySQL 的mysql_secure_installation安全脚本执行过程介绍

     服务器/数据库  2个月前  1.09k

    mysql_secure_installation 是 MySQL 提供的一个安全脚本,用于提高数据库服务器的安全性

    【MySQL基础篇】概述及SQL指令:DDL及DML

    【MySQL基础篇】概述及SQL指令:DDL及DML

     服务器/数据库  2个月前  491

    数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据库不仅仅是数据的简单堆积,而是遵循一定的规则和模式进行组织和管理的。数据库中的数据可以包括文本、数字、图像、音频等各种类型的信息。

    Redis中的哨兵(Sentinel)

    Redis中的哨兵(Sentinel)

     服务器/数据库  2个月前  316

    ​ 上篇文章我们讲述了Redis中的主从复制(Redis分布式系统中的主从复制-CSDN博客),本篇文章针对主从复制中的问题引出Redis中的哨兵,希望本篇文章会对你有所帮助。