数据库分表实践

目录

前言

如何分表

分表带来的问题

跨库事务

分页查询,排序问题

联表问题

二次分表

一致性ID


前言

如果单表的数据量过大,则会影响查询效率。想要解决这个问题,显然,直接拆分就完事了。一张表的数据量过多,那么进行分表,将数据分散到多张表中,每张表中的数据自然就不多了,问题就迎刃而解了。

针对单表数据量大的情况,分库分表就是一个通用的解决方案。可以细分为三种:

  1. 只分表不分库:主要用于解决单表数据量大问题
  2. 只分库不分表:主要用于解决数据库并发量大问题
  3. 分库分表:解决并发量大且数据量大问题

在实际工作中,虽然没有遇到过并发量过大需要分库,也没遇到过单表数据量过大不得不分表的情况,但是在实践中也设计过分表,主要是缓解老板对数据持续增长导致单表数据量过大影响查询效率的焦虑,就在设计表结构时做了冗余设计,考虑了以后数据量过大的问题,就预先对数据量会比较多的表进行了分表。

如何分表

定下来要分表的技术方案后,那么就要考虑怎么分表了,按什么来分?

分表字段

分表字段需要根据实际的业务情况来确定,以公司的业务为例,公司的产品是一个多租户的互联办公saas平台,每个企业相当于一个租户,不同的企业之间数据相互隔离。所有的业务中基本上都会有一个企业id,所以在进行分表时,就是根据企业id来进行分表的。

这么分表的一个好处就是,同一个企业下的所有数据都会分配到同一张表下,这样能够避免分表带来的跨表分页查询,联表查询,排序问题。

分表数量

确定了分表的字段,接下来就要确定分表的数量了,同样是根据实际业务情况,预估数据量的大小来确定分表的数量,但是数量一定要是2的整数幂

类似于HashMap的扩容算法

选择2的整数幂作为扩容的大小是因为HashMap内部的计算哈希索引的方法是通过对数组长度取余,使用2的整数幂作为数组长度,可以通过位运算实现取余操作,这比使用除法运算更加高效。

同理,使用2的整数幂来分表,就能够使用位运算来提高效率。

JDK1.8 的HashMap在扩容时,不需要重新计算元素的hash进行元素迁移。
而是用原先位置key的hash值与原数组的长度(oldCap)进行"与"操作。

  1. 如果结果是0,那么当前元素的桶位置不变。
  2. 如果结果为1,那么桶的位置就是原位置+原数组 长度

同理,在二次分表时,不用将原有的数据全部都再分一遍。只需将分表字段的hash值与原分表数量进行与(&)操作。

  1. 如果结果为0,那么数据不用迁移
  2. 如果结果为1,则将数据迁移到 原分表索引号 + 原分表数量(例如:二次分表前只有 2 张分表 t0 t1;那么二次分表后就会有 4 张分表 t0 t1 t2 t3;如果 t0 中的某条数据分表字段的hash值与原分表数量(2)的与(&)操作结果为1,那么这条数据就要迁移到 0 + 2,也就 t3 这张表中)

分表算法

确定了分表字段和分表数量后,就可以确定分表算法了

实际上就是根据分表数量取模而已,分表数量时2的整数幂的话,则可以用位运算代理

如果分表字段本身就是数值,那么就可以直接对分表字段进行取模

若分表字段不是纯数值,则需要先进行一遍hash后,再进行取模

以上是根据实际业务确定的分表字段后的分表方案

实际上有些业务可以通过一些关键字来分表,比如 日期地区 等等来进行分表,按这些关键字来分表的,其实就不需要考虑什么分表字段和分表数量了,不需要取模得到分表索引了。每个关键字做后缀就是一张分表了。

分表带来的问题

跨库事务

如果涉及到跨库事务,最省事的方法实际上就是直接上分布式事务中间件了,比如 Seata

本文只讨论分表的情况,跨库事务实际项目中没有实践过,个人感觉分布式事务实在是太重了,不到万不得已真的不想引入。(这题我不会

分页查询,排序问题

确定好分表字段后,可以确保业务上的关键查询的数据都在同一张表下,这些问题就可以转换为单表下的分页查询,排序问题了。

但是这并不是一劳永逸的,以上解决的只是使用分表字段的关键查询,若是要用非分表字段来做查询,这些问题时避免不了的。如果业务上一定存在这些查询的话,那么就需要将这些数据同步到 ES 中来做查询了。

联表问题

显然,在分表数量不多的时候,在代码中直接一张张表去做联表查询,然后再汇总,确实能够解决,但是分表的数量一旦多起来,就显得很笨了,使用 shardingsphere 中间件实际上是同样的,只不过是由自己手动写代码变成了 shardingsphere 来做

针对联表问题,使用数据冗余来解决是相对优雅的,利用空间来换取时间。

或者也可以将数据同步到 ES 中,交给 ES 来做查询

二次分表

使用2的整数幂来扩容分表数量,详情参考上面如何分表的描述

一致性ID

传统单表的ID是通过自增主键来生成,但是分表后由多张表显然就无法使用自增ID了,虽然可以每张表使用不同的步长来做自增主键,但是面临二次分表的话,所有的主键又得重新更改了,而且步长也得做调整,这种方案显然只能用在一开始就确定不用二次分表的业务场景中。

使用UUID的话,虽然保证了一致性,但是不是有序的ID,每次插入都有可能导致底层数据结构重新排序一遍,严重影响效率。

最好的方法就是使用现成的雪花算法,生成的ID总共有64个bit

1 bit 符号位 41 bit 时间戳位 10 bit 工作进程位置 12 bit 序列号位

每毫秒最多生成 1024 * 4096 = 4194304 个ID

在一般的小公司的业务中,使用雪花算法确实有点杀鸡用宰牛刀的感觉,实际上自己也可以基于时间戳来生成一个一致性ID,应付小公司的业务绰绰有余了,代码能跑就行,早点下班。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/48796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享一个最近在进行前后端联调时改了2天的bug...

场景再现 我们这边前端端口是8080 后端端口是8121 我们在前端里在首页面写了一个任务 当进入网页三秒后 发起一个叫getLoginUser的请求 我们的getLoginUser是调用的这里 一个异步请求 这边我们前端调用后端的接口也已经写好 我们先把后端跑起来 访问前端页面 接收到了这个…

数学建模学习(112):FAHP模糊层次分析法

文章目录 一、FAHP方法由来二、模糊层次分析法原理2.1 AHP缺陷2.2 模糊集理论2.3 模糊层次分析法(FAHP)三、模糊层次分析法步骤3.1 问题定义与层次结构建立3.2 构造模糊判断矩阵3.2.1 计算模糊判断矩阵的列和向量3.2.2 计算模糊综合向量3.2.3 计算模糊权重向量3.3 解模糊数3.…

搜维尔科技:Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作

Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作 搜维尔科技:Manus Metagloves使用精确的量子跟踪技术捕捉手部每一个细节动作

Ubuntu 22.04.4 LTS (linux) Tomcat 9 内存和线程优化

1 Apache Tomcat 9.0.91 线程 #在70行左右,增加如下 sudo vim /data/tomcat/conf/server.xmlmaxThreads"800" #客户请求最大线程数minSpareThreads"200" #最小线程数maxSpareThreads"500" #最大线程数acceptCount"800"…

监控易V7.6.6.15全新升级14:设置功能全面优化

随着企业IT架构的不断发展,对运维管理的需求也日益增加。为了满足广大用户对运维管理的更高需求,监控易系统近期完成了一次重要版本升级。本次升级在原有功能的基础上,对设置功能进行了全面优化和新增,旨在为用户提供更加灵活、高…

数据结构【没头单链表】

目录 ​ 概念与结构 结点 链表的性质 链表的打印分析 实现单链表: 创建单链表数据 申请空间 尾插数据 打印 头插数据 尾删 头删 查询数据 指定位置前插入数据 指定位置后插入数据 删除pos节点 删除pos后面的节点 销毁 链表的分类 链表说明&#…

RK3568笔记四十二:OLED 屏幕驱动(模拟I2C)

若该文为原创文章,转载请注明原文出处。 本篇记录使用GPIO模拟I2C驱动OLED屏幕,显示界面效果如下。 主要流程是,修改设备树,使用普通IO口,驱动模拟I2C方式,应用程直接传输数据控制。 1、修改设备 2、编写…

LeetCode刷题记录(第三天)55. 跳跃游戏

题目: 55. 跳跃游戏 标签:贪心 数组 动态规划 题目信息: 思路一:动态规划 确定dp数组含义: dp[i] 第[i]个位置能否达到确定递推公式: dp[i] 能不能达到,取决于前面d[i-j],d[i-j…

Docker无法拉取镜像!如何解决?

问题现象 继去年Docker Hub被xxx后,各大NAS的注册表均出现问题,例如群晖的Docker套件注册表无法连接(更新至DSM7.2版本后恢复)。而在今年2024年6月初(约2024.06.06),NAS中最重要的工具Docker又…

【云原生之kubernetes实战】在k8s环境下部署go-file文件分享工具

【云原生之kubernetes实战】在k8s环境下部署go-file文件分享工具 一、go-file介绍1.1 go-file简介1.2 go-file特点1.3 go-file使用场景二、本次实践介绍2.1 本次实践简介2.2 本次环境规划2.3 本次实践存储介绍2.4 k8s存储介绍三、检查k8s环境3.1 检查工作节点状态3.2 检查系统p…

解决数据卷root权限问题的Docker科研向实践思路

Docker好处多多。对用户,最大程度解决环境配置时权限困扰;对运维,方便控制资源分配调度。Docker的科研常用方法为每个用户自行创建容器,代码数据分离,数据以数据卷(Volume)的形式从宿主机&#…

常用设计模式总结

设计模式是在软件开发过程中经常遇到的问题的通用解决方案。它们是经过无数的验证和经验积累的最佳实践。 首先,设计模式是一些前人经验的一些总结,所以,当遇到相似的问题的时候,我们可以直接借鉴好的设计模式来实现,…

02 JDBC

文章目录 JDBC1、JDBC概述2、JDBC快速入门3、JDBC API详解4、数据库连接池5、案例代码 JDBC 1、JDBC概述 JDBC概念 (1)JDBC 就是使用Java语言操作关系型数据库的一套API (2)全称:( Java DataBase Connectivity ) Java…

docer笔记3

docker笔记3 容器基本命令 容器基本命令 下载镜像 docker pull cento新建容器并启动 docker run [可选参数] image# 参数说明 --name“Name” 容器名字 tomcat01 tomcat02 用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查…

R-CNN 中的区域建议网络

区域建议网络(Region Proposal Network,RPN)是R-CNN(Regions with Convolutional Neural Networks)架构中的一个关键组件,特别是在Faster R-CNN中。RPN的主要任务是生成可能包含物体的区域提议,…

【基础篇】1.9 硬件基础(一)

写在前面: 学习STM32微控制器时,具备一定的硬件基础确实是有必要的。虽然STM32是一款功能强大的微控制器,但要充分利用其功能,理解其工作原理,以及进行有效的开发和调试,都需要对硬件有一定的了解。 了解电路的基本原理,有助于理解STM32的引脚配置、电源电路、信号调理…

【总结】cache映射对比

全相联映射的好处是可以随便放,不容易浪费,而直接映射的好处是容易定位,好找。 全相联映射的好处在于其灵活性。在这种映射方式下,主存中的任意一块都可以映射到Cache中的任意一块位置上。这意味着Cache的利用率相对较高&#xff…

什么是机器学习以及机器学习如今的社会现状!!

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

用太空办公桌spacedesk把废旧平板利用起来

正文共:1500 字 15 图,预估阅读时间:2 分钟 这些年积攒了不少电子设备,比如我现在手头上还有6部手机、4台电脑、2个平板。手机的话,之前研究过作为Linux服务器来使用(使用UserLAnd给华为平板装个Linux系统&…

Web 3.0革新:社交金融与边玩边赚开启用户数据主权时代

目录 Web 3.0与社交商业模式 传统社交平台的问题 去中心化社交创新 Mirror:去中心化内容发布平台 Lens Protocol:去中心化社交图谱 Maskbook:隐私保护的社交方式 Web 3.0与与边玩边赚模式 经济模型解析 新商业模式的探索 Axie Infi…