几种水平分表方案与具体实践

玩转MySQL:一站式解决分库分表后患问题方案 上篇分库分表文章中已经将分库分表的方法论全面阐述清楚了,总体看下来用一个字形容,那就是爽!尤其是分库分表技术能够让数据存储层真正成为三高架构,但前面爽是爽了,接着一起来看看分库分表后产生一系列的后患问题,注意我这里的用词,是一系列而不是几个,也就是分库分表虽然好,但你要解决的问题是海量的。 阅读详情
AI摘要

本文探讨了水平分表的必要条件、维度选择技巧、非分表key查询处理和多种实现方式,重点讲解了如何根据业务场景合理分表以提高查询性能。

最近在写水平分表,调研总结实践了一些比较普遍的方法,下面总结一下。

水平分表

所谓水平分表,顾名思义,就是由于某个单表数据过多,影响查询效率,于是选择分表,将原来的业务表按某个维度拆分成几个表,查询的时候根据维度限定选择对应的维度分表去查。比如常见情况下的a表,我按某个维度把它分成了a_1,a_2,a_3。那么当我要查1的数据就去查a_1,查2的数据就去查a_2.

前提条件

  • 最最前提,主键要唯一,有很多实现方法,比如可以针对不同分表设置不同步长来实现,也可以通过雪花算法,uuid来生成分布式唯一id,一般情况下,用后者比较多。

  • 不要过度分表或分库,要从实际需求出发,可以是已经碰到的情况下,也可以是预估出不分表不行的情况。

  • 所要分的表与其他表关联度不是很大,如果它经常被做连接查询,而且它的主键在别的表经常以外键形式存在,那么就不建议直接水平分表,可以先考虑垂直分表把数据量大的部分独立出去再做水平切分。

维度的选择

维度的选择方法有很多,一般情况下,我们可以分成以下几种情况。

  • 按时间分表:这种情况是比较普遍的选择,绝大多数业务表的场景是很少有具体的隔离情况。我们比较简单的选择就是按照时间分表,选择雪花算法,在查询的时候拦截主键,从主键中获取分表key,选择查询的范围。举一个最常见的例子,比方说电商平台的订单表order,我们根据时间分成order_2010_2020,order_2020_2030,表示时间在2010年到2020年与2020年到2030年的表。在进行插入更新时候,选择当前时间属于的时间区间替换表名并插入,查询的时候则选择主键中的时间部分进行表名的替换再进行改写sql查询。
  • 按id取模分表:适用于区分表的业务属性不大相关的情况,没有明显的特征,只要单纯将数据按一定规格拆分,比方说一百万条数据分成3个表,只需要id对3取余即可。
  • 按某一字段分表:针对表中的某一字段进行分表,举个具体例子,仍然是订单表,订单里存了一个属性叫地区,按地区分表。那么只需要在每次查询的时候带上这个地区即可,同样的根据userid范围分表也是一样的道理。
  • 按不存在于数据库的情况分表:这种情况分几种类型,即分表的字段存在数据库外,有时来自上下文,有时来自实例里的yml配置。这时候需要我们在业务层做强制路由即可实现。

针对非分表key的查询处理

针对有些情况没有分表key的情况也是比较普遍的,比方说一个c端与b端之间的平台类项目,往往在选择分表key的时候会出现顾守不顾尾的情况。这个时候总要牺牲一端的用户体验。比方说针对userid对order表分表,那么c端用户查询确实是便利了,但是b端用户就很难找到这个userid,这个时候我们一般有几种处理方法:

  • 改写sql走union查询:这种方式问题比较大,一方面是由于union效率比较低,做排序分页等查询问题也比较大,另一方面如果使用mybatis-plus之类的工具,使用拦截器插件进行开发分表功能的话,如果我们进行查询的时候参数拼接重写会有参数无法注入的问题。具体来说比方说select * from a where id = 1.那么分表之后的查询变成了(select * from a_1 where id = 1) union (select * from a_2 where id = 1);但在mp框架里会出现参数集为1,待重写阶段的sql为select * from a_1 where id = ?,这样的在一句sql里面出现了两个问号,但是没法填充。当然如果对mp源码理解比较深的话,可以把参数重写。即扩充一倍即可。
  • 双写:另外搞一个主库或者主表,比较简单,每次插入更新的时候都做两次,主表的话加个事务问题不大,如果加个主库的话,则要注意保证一致性,可以考虑消息队列或者binlog之类的处理方法。
  • 更改业务逻辑,这种方法一般不太可能,也有特殊情况。

分表具体实现形式

  1. 第一种做法的话就是使用成熟的框架,比方说mycat和sharding-jdbc这种,业务侵入比较小,也比较方便,具体代码官网示例也写的较为清楚,当然对于一些团队没有接触过的东西,学习周期就会相对长一点。
  2. 第二种做法的话使用插件自行开发,其实就是拦截sql并改写。下面以mybatis-plus插件为例,参照官网的分页插件可以写出分表插件,自行实现。
@Intercepts(
        {
                @Signature(
                        type = StatementHandler.class,
                        method = "prepare",
                        args = {Connection.class, Integer.class}
                )
        }
)
public class TableShardInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement)
                metaObject.getValue("delegate.mappedStatement");
        String id = mappedStatement.getId();
        id = id.substring(0, id.lastIndexOf('.'));
        Class clazz = Class.forName(id);
        
            String sql = (String) metaObject.getValue("delegate.boundSql.sql");
            metaObject.setValue("delegate.boundSql.sql", strategy.rewriteSql(sql, tableName));
       //这里的rewirite todo写具体的逻辑。
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身, 减少目标被代理的次数
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
为什么你的水平分表越分越慢?这些坑90%的人都踩过! 面试被问到“做过分库分表吗?”时,别慌!水平分表可不是简单地“拆表”,它背后藏着性能优化、ID生成、事务一致性等一连串深坑。本文小米用一个真实项目故事,带你轻松搞懂水平分表的原理、策略与实战经验。 阅读详情

相关推荐

Python逆向爬取Tik Tok,MsToken,X-Bogus以及signature

tiktok作为字节海外的自媒体平台,具有很非常大的价值,本文旨在教会大家实现Tik Tok的签名获取以及数据的最终爬取。

weixin_74305707的博客 3268

水平分表与垂直分表

水平分表 垂直分表

MAKABAKA__ZJC的博客 8900

使用【阿里云百炼】搭建自己的大模型

本文介绍阿里云百炼大模型平台,其为企业级服务平台,融合通义千问等模型,支持多模态能力,提供一站式工具降低开发门槛。重点讲解智能体应用及大模型搭建步骤,含进入创新应用界面、选模型配参数、输指令、导数据、加载知识库、获取API Key、加样例库、配置MCP,还提及模型调试与多平台发布,并附试用链接,助力企业与开发者快速搭建适配业务的AI模型。

Larry的博客 4738

mysql基础知识篇(六)

例如,现在的用户是 100 万,如果增加到 1000 万,只需要增加新的表就可以了,原有的数据不需要动。同样以订单 id 为例,假如我们一开始就规划了 4 个数据库表,路由算法可以简单地用 id % 4 的值来表示数据所属的数据库表编号,id 为 12 的订单放到编号为 50 的子表中,id 为 13 的订单放到编号为 61 的字表中。还有可以适当的冗余一些字段。创建一个临时的新表,把旧表的结构完全复制过去,添加字段,再把旧表数据复制过去,删除旧表,新表命名为旧表的名称,这种方式可能回丢掉一些数据。

恒二哥的博客 1087

基于pytest+Allure+Python+CANoe的汽车诊断自动化测试框架搭建实战

自动化测试是提升软件质量和研发效率的关键技术,其核心原理是通过脚本模拟人工操作,实现测试用例的自动执行与结果验证。在汽车电子领域,诊断服务测试是确保车辆ECU(电子控制单元)功能正常的重要环节,传统手动测试在面对海量用例和频繁回归时效率低下。本文聚焦于如何利用Python的pytest测试框架、Allure报告工具以及Excel数据驱动,构建一个与Vector CANoe仿真测试环境深度集成的自动化测试解决方案。该方案通过Python调用CANoe的COM接口,实现了诊断报文的自动发送与响应验证,并结合Al

weixin_30384217的博客 677

周立功CAN盒二次开发实录:用QT5.1.0解析汽车CAN报文(附数据可视化技巧)

本文详细介绍了基于QT5.1.0和周立功USBCAN-E-U设备进行汽车CAN总线二次开发的实战过程。核心内容包括利用CANdb++数据库解析原始报文并转换为物理值,以及通过QCustomPlot库实现高性能实时数据可视化,为车载诊断与车联网开发提供了一套完整的工程实践方案。

sugar的博客 1057

水平分表

概述 当一个表的数据很大,比如200G,这时太大,我们只靠索引也不好使了,这时我们需要分表和分区处理。分表有两种形式(水平分表和垂直分表)。 一、水平分表   核心思想:把一个大表,分割N个小表,小表和大表结构一样,只是把数据分散到不同的表中。 简单例子:比如说是通过ID直接登录(例如QQ号),可以直接使用下面的例子 每次登录验证的时候只要把传过来的Id...

不求前途凶吉,但求落幕无悔! 6459

可信数据空间关键技术和功能架构研究

可信数据空间(TDS)是实现数据安全共享的基础设施,通过数字合约和使用控制技术确保数据跨域流通的可信与安全。其架构包括服务平台和接入连接器,关键技术涵盖访问控制、隐私计算、区块链等。评估重点在于合规性、连接器能力、互联互通及安全体系。核心在于构建规则引擎而非简单数据汇聚,连接器开发比平台建设更重要。当前面临技术成本博弈、跨域身份互认等挑战,需平衡安全、性能与成本,推动数据要素市场发展。

逸尘的专栏 2222

MySQL之水平分表策略

水平分表是一种将数据表按一定规则拆分为多个子表的技术。每个子表存储全表数据的一部分,所有子表共同组成完整的数据集。通过这种方式,可以减小单表的数据量,提高查询和操作的性能。MySQL 水平分表策略是应对大数据量下数据库性能问题的有效手段。不同的分表策略适用于不同的业务场景,选择合适的分表策略可以大大提升数据库的性能和可扩展性。在实施水平分表时,需要综合考虑数据的分布、查询需求、系统复杂度以及未来的扩展性,才能获得最佳效果。

专注于Python编程技术的分享与交流,致力于帮助开发者提升编程技能,解决实际问题,探索Python的无限可能。 2564

基于深度确定性策略梯度的永磁同步电机强化学习控制方法

本文提出了一种基于深度确定性策略梯度(DDPG)的永磁同步电机(PMSM)电流内环智能控制方法。首先建立了PMSM在d-q坐标系下的数学模型,分析了传统矢量控制双闭环系统中PI控制器的局限性。针对电流内环控制问题,设计了包含电流跟踪误差、转速信息和历史控制量的状态空间,将电压输出作为动作空间,并构建了兼顾跟踪精度和响应速度的奖励函数。通过DDPG算法训练智能体,使其能够自适应调整控制策略。仿真结果表明,与固定参数的PI控制器相比,DDPG控制器在动态响应速度和抗干扰能力方面具有明显优势,为PMSM高性能控制

huanghm88的专栏 103

【24届数字IC秋招总结】正式批面试经验汇总6——禾赛

15、ahb写或者读的数据存储起来了嘛,ahb读的话,apb这边是怎样的。19、覆盖率收集的时候有没有哪些是很难收集到的,然后写了定向测试。2、C++有学过嘛 还记得C++的什么内容 C++成绩多少。12、config_db机制用过嘛 四个参数的含义。8、脚本语言有学过嘛 简单学过 简单是指代码数少嘛。13、run_phase和mian_phase的区别。10、覆盖机制的创建方法 ,是不是覆盖用的很少。6、call_back机制记得哪些细节的东西。9、uvm实战学了哪些章节 印象深刻的章节。

qq_42135020的博客 1083

MySQL水平分表原理讲解

什么是水平分表? 当一张表到达一定的数据量后(如500万条数据),索引的成本也随之增加,使用主键索引查找数据时也显得十分吃力,数据检索效率低。 水平分表是将一个数据量大的表按照一定的规则拆分成多个结构相同的表,将数据分散到拆分出来的表中。拆分后,当我们查找某条数据时,只需要按照拆分表时的规则推断出需要查询的数据具体存在哪一张表中,到对应的表查找数据即可。 下图是按照时间作为规则水平拆分表的示例: 常见的水平分表方案 1.按时间拆分 像上图中的拆分示例,采用的是按照年份水平拆分表的方案,除此之我们还

云丶言的博客 4581

利用人工神经网络在Abaqus中实现本构模型的网格粗化计算框架:详细指南与实践

在这篇文章中,我们详细介绍了如何在Abaqus中实现基于人工神经网络(ANN)的本构模型以进行网格粗化的计算框架。我们通过两个主要模块——数据生成器模块和ANN训练模块,实现了这一计算框架,并将训练好的ANN集成到Abaqus的用户材料子程序(UMAT)中,创建了一个基于ANN的本构模型。我希望这篇文章能帮助到那些希望在Abaqus中实现基于ANN的本构模型的读者,同时,我也非常欢迎大家提出宝贵的意见和建议,让我们共同进步。

qq_38334677的博客 1715

【SQL】水平分表有哪几种路由方式

⽔平分表有哪⼏种路由⽅式

hui_zai_的博客 862

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【分库分表问题————水平分表】

选择水平分表策略时,需要根据具体的业务需求和数据特点来决定。数据分布的均匀性查询和更新操作的频率和类型系统的扩展性要求数据倾斜和热点问题综合考虑这些因素,可以选择合适的分表策略来优化数据库性能和可扩展性。参考文章:https://blog.youkuaiyun.com/xiaowanzi_zj/article/details/122270389。

weixin_43571244的博客 1753

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Mycat水平分表

项目中一张表的数据量不断的增大,这样到导致了数据查询效率底下,这个时候我们通常可以采用水平分表,将该表进行水平切分保存在不同的数据库中。 分配策略:可以按照id的生成规则区,也可以按照用户存在的地理位置区分等等。 如: 步骤: 1.配置schema.xml <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTE...

喝醉的咕咕鸟 914

Oracle 水平分表: 从原理到实战的完整指南

水平分表(Horizontal Table Splitting)是指将一张大表的行数据, 按照某种规则拆分到多个结构完全相同的子表中. 拆分后, 每个子表包含原表的一部分行, 所有子表合起来构成完整的数据集.fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;拆分后:按年份分表拆分前:单表t_orders1亿行2500万行3500万行。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 661

mysql水平分表 垂直分表_Mysql的水平分表与垂直分表的讲解

在我上一篇文章中说过,mysql语句的优化有局限性,mysql语句的优化都是围绕着索引去优化的,那么如果mysql中的索引也解决不了海量数据查询慢的状况,那么有了水平分表与垂直分表的出现(我就是记录一下自己的理解)水平分表: 如上图所示:另外三张表表结构是一样的 只不过把数据进行分别存放在这三张表中,如果要insert 或者query 那么都需要对id进行取余 然后table名进行拼接,那么就...

weixin_39958559的博客 255

水平分表路由方式及优缺点

水平分表是数据库水平切分(水平分区)的一种形式,它将数据表按照某个字段的值进行分割存储在不同的物理表中。在水平分表中,通常采用路由方式来确定数据应该存储在哪个具体的物理表中。总的来说,水平分表路由方式各有优缺点,选择合适的方式取决于具体的业务需求、数据特点以及系统性能等因素。在实际应用中,通常需要根据实际情况进行权衡和选择。

xzz的博客 587

如何应对MySQL单表数据量过大:垂直分表与水平分表策略解析

话接上回,单表最大数据建议两千万,那如果开发一个项目,预计注册量达到一个亿怎么办。单表内放这么多数据,MYSQL底层B+树的层级结构就可能会变得很高,磁盘io次数变多,性能会大幅度降低。所以考虑数据库分表。这里的分表分为垂直分表和水平分表两种。

weixin_62647396的博客 861

数据库优化理论——大表的优化方式、垂直分表、垂直分库、水平分表、水平分库、主从复制等

MySQL复制:为保证主服务器和从服务器的数据一致性,在向主服务器插入数据后,从服务器会自动将 主服务器中修改的数据同步过来。I/O线程:负责从主服务器上读取二进制日志(Binary log),并写入从服务器的中继日志(Relay log)中。SQL线程:负责读取中继日志,解析出主服务器中已经执行的数据更改并在从服务器中重放 复制过程如下。主从复制的原理: 主从复制主要有三个线程:binlog线程,I/O线程,SQL线程。

qq_44182424的博客 1143

mysql垂直分表好处_mysql水平分表和垂直分表的优缺点

Mysql中分区和分表有什么区别,各自的优缺点是什么当数据库表中数据量能够被预测到将会非常大,或者已经拥有庞大的数据时,我们应该选择分表或者分区(即使用多个数据库)来解决数据访问时的性能问题。如果单机的cpu能够承受站点的并发数,应该选择分表的方式,因为分表相对简单。mysql水平分表和分区有什么区别?水平分表和分区都是拆分成物理表,分区实现更简单,方式更多样,为什么网页链接转载自chuquan....

weixin_39989980的博客 835

mysql中的优化, 简单的说了一下垂直分表, 水平分表(有几种模运算),读写分离.

一、mysql中的优化 where语句的优化 1.尽量避免在 where 子句中对字段进行表达式操作 select id from uinfo_jifen where jifen/60 > 10000; 优化后: Select id from uinfo_jifen where jifen>600000; 2.应尽量避免在where子句中对字段进行函数操作,这将导致mysql放弃...

一只苟延残喘的卑微蝼蚁 422

水平分表常见的路由算法

水平分表后,某条数据具体属于哪个切分后的子表,需要增加路由算法进行计算。 常见的路由算法有如下几种: 1)范围路由 以最常见的用户ID为例,路由算法可以按照1000000的范围大小进行分段,1~999999放置于数据库1的表中,1000000~1999999放到数据库2的表中,以此类推。 优点:随着数据的新增可以平滑地扩充新的表。缺点是分布可能不均匀。 2)...

kieven2008的专栏 1330

图文并茂 | 水平分表的路由策略有哪些?什么是一致性哈希?

本文讲了什么是水平分表,以及几种常见的水平分表路由策略,每种策略的优缺点,最后讲了一致性哈希

大数据的奇妙冒险 702
上一篇: 回首2020,展望2021
下一篇: 一个由Java泛型类型擦除引起的问题
Tate_Brown
博客等级 码龄9年 39粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值