概述

在实际工作中,在关系数据库(MySQL、PostgreSQL)的单表数据量上亿后,往往会出现查询和分析变慢甚至无法执行统计分析的情况。这时就需要将大表拆分为多个小表,将小表分布在多个数据库上,形成一个数据库集群。这样的话,一条 SQL 统计语句就可以在多台服务器上并发执行,然后将执行结果汇总,实现关系数据库的大数据量分析

数据库三范式

范式是具有最小冗余的表结构,三范式的概念如下所述

第一范式:如果每列都是不可再分的最小数据单元,则满足第一范式,第一范式的目标是确保每列的原子性。例如 Address 列存储地址信息,值为“中国北京市”,违背了第一范式列不可再分的原则,要满足第一范式,就需要将 Address 列拆分为 Country 列和 Ciy 列,分别存储“中国”和“北京市”

第二范式:第二范式在第一范式的基础上,规定表中的非主键列不存在对主键的部分依赖,即第二范式要求每个表都只描述一件事情。例如 Orders 表有“订单编号”,“产品编号”,“订单日期”,“产品价格”列,既包含了订单信息,也包含了产品信息,需要拆分成订单表和产品表

第三范式:满足第一范式和第二范式,并且表中的列不存在对非主键列的业务依赖。例如 Orders 表有“订单编号”,“顾客编号”,“订单日期”,“顾客姓名”列,除了主键“订单编号”,“顾客姓名”依赖于“顾客编号”,因此需要将该“顾客编号”移去

按照范围分表

按照范围分表指在某个字段上按照范围对数据进行拆分,例如将数据按照用户 ID 的范围 0-10w、10w-20w、20w-30w 分别划分到不同的数据库中。采用这种方法扩容简单,按照规划提前建好库和表即可,缺点是大部分读和写操作都会访问新的数据,造成新库压力过大

哈希取模

哈希取模指在某个字段上计算该字段的哈希值,按照其哈希值对数据进行拆分。哈希取模的具体做法是首先对 N 台服务器从 0 到 N-1 进行编号,按照自定义的哈希算法,对每个请求的哈希值都按 N 取模,得到的余数即该数据所在的服务器编号。采用该方法的好处是数据分布均衡,数据库的整体压力小,缺点是扩缩容麻烦,在扩缩容过程中需要对所有数据重新进行哈希分配和迁移

一致性哈希算法

一致性哈希算法取代传统的哈希取模,避免服务器集群数量发生变化导致哈希值失效,以致整个集群数据都需要重新分配的问题

一致性哈希算法将整个哈希空间虚拟成一个 0-2^(32-1) 的哈希环,将服务器节点和数据分别映射到哈希环上,并将对象映射到服务器节点,来实现数据在各台服务器上的哈希分

布,具体过程如下:

构建哈希环:将整个哈希空间组成一个 0-2^(32-1) 的虚拟圆环,即哈希环,如图所示

将服务器节点映射到哈希环:使用哈希函数将服务器映射到虚拟的哈希环上,一般可以使用服务器节点机器的 IP 地址或者机器名作为哈希函数的计算值。假设有 3 个服务器节点:node-0、node-1、node-2,通过哈希函数计算出服务器 IP 地址的哈希值,并将其分布在哈希环上

将数据映射到哈希环:使用相同的哈希函数计算需要存储的数据的哈希值,并将数据映射到哈希环上。假设有 4 个对象:o1、o2、o3、o4,通过哈希函数计算出对象的哈希值,并将其分布在哈希环上

将对象映射到服务器节点:找到对象的哈希值在哈希环上的位置,从该位置开始沿哈希环顺时针寻找,遇到的第 1 台服务器就是该对象的存储节点服务器,将该对象映射

到该服务器上。如图所示,对象 o1 被映射到 cs1 上,对象 o2 被映射到 cs2 上,对象 o3 被映射到 cs1 上,对象 o4 被映射到 cs3 上

传统的哈希取模,当服务器有变动(增加节点或移除节点)时,整个系统的哈希值都会失效(因为服务器的数量发生了变化,即被除数发生了变化),从而需要重新计算哈希值,并进行哈希映射和数据分布。而一致性哈希在服务器发生变动时,由于对象的数据分布只与顺时针方向的下一台服务器相关,因此只会影响所变化节点的下一个节点的数据分布

移除节点:假设某台服务器宕机,受影响的对象仅仅是原本映射到该服务器的对象,根据一致性哈希顺时针数据映射的原则,只需将原本映射到该服务器上的对象重新映射到下一个正常的服务器即可。例如 cs1 宕机,只需将 o1 重新映射到 cs3 即可

添加节点:添加节点,受影响的数据仅是新节点到沿逆时针方向的第一个节点之间的对象,将这些对象重新映射到新加入的节点即可。例如在 cs1 和 cs2 之间加入新节点 cs3,cs3 位于 o1 和 o3 之间,只需要将 o3 重新映射到 cs3 即可

一致性哈希算法不能保证数据的绝对平衡,在集群对象数据较少的情况下,对象并不能被均匀映射到各个节点上。为了解决数据分布不均的问题,一致性哈希算法引入“虚拟节点”的概念。虚拟节点是实际节点在哈希空间中的副本,一个实际节点对应若干虚拟节点,对应的个数也被称为副本个数,虚拟节点在哈希空间中以哈希值排列。在引入虚拟节点后,映射关系就从对象到节点转换为从对象到虚拟节点

MySQL 大表拆分的更多相关文章

  1. 优秀后端架构师必会知识:史上最全MySQL大表优化方案总结

    本文原作者“ manong”,原创发表于segmentfault,原文链接:segmentfault.com/a/1190000006158186 1.引言   MySQL作为开源技术的代表作之一,是 ...

  2. MySQL 大表优化方案(长文)

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

  3. [记录]一则清理MySQL大表以释放磁盘空间的案例

    一则清理MySQL大表以释放磁盘空间的案例 一.基本情况: 1.dbtest库554G,先清理st_online_time_away_ds(37G)表的数据,保留半年的数据: 1)删除的数据:sele ...

  4. 从云数据迁移服务看MySQL大表抽取模式

    摘要:MySQL JDBC抽取到底应该采用什么样的方式,且听小编给你娓娓道来. 小编最近在云上的一个迁移项目中被MySQL抽取模式折磨的很惨.一开始爆内存被客户怼,再后来迁移效率低下再被怼.MySQL ...

  5. MySQL把一个大表拆分多个表后,如何解决跨表查询效率问题

    大表分表后每个表的结构相同,可以用sql的union 比如a,b表结构相同可以通过union来联接 select * from aunion allselect * from bwhere.... 其 ...

  6. mysql 大表拆分成csv导出

    最近公司有一个几千万行的大表需要按照城市的id字段拆分成不同的csv文件. 写了一个自动化的shell脚本 在/home/hdh 下面 linux-xud0:/home/hdh # lltotal 1 ...

  7. 详解MySQL大表优化方案( 转)

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

  8. MySQL 大表优化方案探讨

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

  9. MySQL大表优化方案

    转:https://segmentfault.com/a/1190000006158186?hmsr=toutiao.io&utm_medium=toutiao.io&utm_sour ...

  10. MySQL 大表优化方案

    当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型 ...

随机推荐

  1. Linux自己制作rpm包

    制作rpm包 由源码包---->rpm包 安装制作rpm包工具包rpm-build 在制作过程中需要源码包和配置文件 rpmbuild制作rpm包的原理: 1.首先rpmbuild会先将源码包进 ...

  2. Error: Dynamic require of "path" is not supported

    failed to load config from D:\BaiduSyncdisk\vue3\sys-manager\vite.config.jserror when starting dev s ...

  3. 理解es6 Promise的resolve和reject方法

    Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用. const jsPromise = Promise.resolve ...

  4. JavaScript一天一个算法题~持续更新中。。。。。

    1,数组去重 i.暴力去重 思路:建一个空数组,通过判断原数组的元素是否在空数组内,如果在,不放入,不在,放入空数组. function clearCommnetArray(array){ let a ...

  5. ffmpeg精简

    自:http://www.chinavideo.org/viewthread.php?tid=5567&extra=page%3D1&page=2 现在更新一下目前遇到的问题: 我想裁 ...

  6. 单细胞测序最好的教程(八): 细胞类型自动注释-1|基于marker的自动注释

    作者按 本章节主要讲解了基于marker的自动注释方法,一般来说,我会先自动注释,再手动去确认marker,这是因为,对于一个陌生的组织,我对marker是不了解的,自动注释可以帮助我快速熟悉细胞类型 ...

  7. php 开发规范

    ===========================框架========================= · 使用laravel框架,原因:tp的框架路由和orm没有laravel好用 · 使用强 ...

  8. scratch源码下载 | 炮轰僵尸

    程序说明: <炮轰僵尸>是一款基于Scratch平台制作的游戏程序,它采用了植物大战僵尸的经典场景.在游戏中,玩家需要控制一枚大炮来对抗不断入侵的僵尸.通过移动鼠标,玩家可以调整炮筒的方向 ...

  9. 【RabbitMQ】05 通配符模式

    需要设定交换机模式为通配符模式 Topic 在绑定规则上采用通配描述实现动态绑定 创建通配符模式的生产者 package cn.dzz.topicQueue; import com.rabbitmq. ...

  10. Ubuntu 18.04在已经安装Docker CE后如何安装NVIDIA-Docker,以使docker容器内可以使用宿主机显卡

    注意: 本文是在电脑上已经安装好docker环境的前提下进行的. docker环境如何安装参照前文. 本文内容节选自:  https://baimafujinji.blog.csdn.net/arti ...