当前位置: 首页 > news >正文

分库分表之实战-sharding-JDBC水平分库+水平分表配置实战

大家好,我是工藤学编程 🦉一个正在努力学习的小博主,期待你的关注
实战代码系列最新文章😉C++实现图书管理系统(Qt C++ GUI界面版)
SpringBoot实战系列🐷【SpringBoot实战系列】Sharding-Jdbc实现分库分表到分布式ID生成器Snowflake自定义wrokId实战
环境搭建大集合环境搭建大集合(持续更新)
分库分表分库分表之实战-sharding-JDBC广播表

前情摘要:

1、数据库性能优化
2、分库分表之优缺点分析
3、分库分表之数据库分片分类
4、分库分表之策略
5、分库分表技术栈讲解-Sharding-JDBC
6、分库分表下的 ID 冲突问题与雪花算法讲解
7、分库分表之实战-sharding-JDBC
8、分库分表之实战-sharding-JDBC广播表


【亲测宝藏】发现一个让 AI 学习秒变轻松的神站!不用啃高数、不用怕编程,高中生都能看懂的人工智能教程来啦!

👉点击跳转,和 thousands of 小伙伴一起用快乐学习法征服 AI,说不定下一个开发出爆款 AI 程序的就是你!


本文章目录

      • Sharding-JDBC水平分库分表实战
        • 一、分库分表架构设计与场景分析
        • 二、库表数据清除与配置修改
        • 三、执行结果与分片验证
        • 四、进阶优化与注意事项
        • 五、总结:水平分库分表的核心价值

Sharding-JDBC水平分库分表实战

一、分库分表架构设计与场景分析

前言
项目工程紧接:分库分表之实战-sharding-JDBC广播表。

核心分片策略

  • 分库规则:按user_id取模分片(user_id % 2),确保同一用户的订单集中在同一库
  • 分表规则:按product_order_id(订单号)取模分片(product_order_id % 2),分散单库内的数据压力
二、库表数据清除与配置修改

首先我们将之前章节产生的数据清除,避免印象本章节的测试

在这里插入图片描述

然后application.properties中新增内容,将之前分表规则由user_id改为订单自身的id,并且需要将真实节点改为库+表

#配置分库规则
spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2}#将之前分表规则由user_id改为订单自身的id
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}#原本为ds0.product_order_$->{0..1}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}

在DbTest中新增单元测试函数

@Testpublic void testSaveProductOrderDB(){Random random = new Random();for(int i=0;i<20;i++){ProductOrderDO productOrder = new ProductOrderDO();productOrder.setCreateTime(new Date());productOrder.setNickname("ccc_i="+i);productOrder.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));productOrder.setPayAmount(100.00);productOrder.setState("PAY");productOrder.setUserId(Math.abs(random.nextLong()));productOrderMapper.insert(productOrder);}}
三、执行结果与分片验证

1. SQL执行日志(关键输出)

  • 逻辑 SQL(统一的抽象 SQL):
    逻辑 SQL 是开发者编写的、针对逻辑表的 SQL 语句,不关心数据实际存储在哪个物理库或物理表,是对分库分表逻辑的抽象。
INSERT INTO product_order (id, out_trade_no, state, create_time, pay_amount, nickname, user_id) VALUES (?, ?, ?, ?, ?, ?, ?)
  • 特点
    面向逻辑表:product_order是逻辑表(代表整个分库分表的数据集,而非具体某一张物理表)。
    与分库分表无关:开发者无需关心数据最终存在ds0还是ds1,也无需关心存在product_order_0还是product_order_1。
    参数化:使用?作为占位符,参数由业务代码传入(如id、user_id等)。
    统一抽象:无论数据分布在多少个库表,逻辑 SQL 的写法保持一致,简化开发。
  • 实际 SQL(路由到具体库表):
    实际 SQL 是 Sharding-JDBC 根据分库分表策略,将逻辑 SQL 转换为针对具体物理库和物理表的可执行 SQL 语句。
#路由到ds1.product_order_0:
INSERT INTO product_order_0 (...) VALUES (...) ::: [1942559776326320130, 70bd5220-1c9c-4e3e-b418-85481f60, PAY, 2025-07-08 20:21:56.32, 100.0, ccc_i=0, 204402002533403893]
#路由到ds0.product_order_1
INSERT INTO product_order_1 (...) VALUES (...) ::: [1942559778821931009, 3fe7e14a-e75b-4c44-905e-7cc4efb3, PAY, 2025-07-08 20:21:56.952, 100.0, ccc_i=1, 164530429416077594]
  • 特点
    面向物理库表:
    ds1/ds0是具体的物理库(对应配置中的数据源)。
    product_order_0/product_order_1是具体的物理表(逻辑表product_order拆分后的实际表)。
    由分库分表策略决定:
    分库:根据user_id % 2计算(如user_id=204402002533403893时,204402002533403893 % 2 = 1 → 路由到ds1)。
    **分表:**根据id % 2计算(如id=1942559776326320130时,1942559776326320130 % 2 = 0 → 路由到product_order_0)。
    **包含实际参数:**占位符?被具体值替换(如主键id、user_id等)。
    可直接执行:是数据库能直接识别并执行的 SQL。
    2. 数据库验证(分片结果)
  • ds_0库
    • order_0表:存储user_id偶数、order_id偶数的订单
      在这里插入图片描述
    • order_1表:存储user_id偶数、order_id奇数的订单
      在这里插入图片描述 - ds_1库
    • order_0表:存储user_id奇数、order_id偶数的订单
      在这里插入图片描述
    • order_1表:存储user_id奇数、order_id奇数的订单
      在这里插入图片描述
四、进阶优化与注意事项

1. 分片键选择建议

  • 避免热点问题:若user_id分布不均(如某些用户订单量极大),可考虑复合分片(如user_id + 时间
  • 查询场景优先:分片键需覆盖高频查询条件(如按user_id查询订单时,分片键选择user_id可避免跨库查询)

2. 跨库查询解决方案

  • 广播表关联:若订单需关联商品表,可将商品表设为广播表(参考Sharding-JDBC广播表实战)
  • 分库查询后聚合:复杂跨库查询可通过ShardingSphereStreamResultSet接口实现结果聚合

3. 分布式事务处理
Sharding-JDBC原生支持BASE事务(通过XA柔性事务),若订单涉及跨库更新(如扣库存),需结合Seata等分布式事务框架。

五、总结:水平分库分表的核心价值

通过本案例实现的2库4表架构,可带来以下收益:

  • 性能提升:单表数据量降低,索引查询效率提升30%+
  • 负载均衡:数据分散到多个数据库,CPU/IO资源利用率更均衡

适用场景:订单系统、交易记录、用户日志等数据量大且写入频繁的业务场景。

觉得有用请点赞收藏!
如果有相关问题,欢迎评论区留言讨论~

http://www.lryc.cn/news/582987.html

相关文章:

  • LeetCode题解---<三数之和>
  • 自动化一次通过率
  • 深度学习环境配置:PyTorch、CUDA和Python版本选择
  • 深度剖析:向70岁老系统植入通信芯片——MCP注入构建未来级分布式通信
  • 模型训练篇 | 如何用YOLOv13训练自己的数据集(以明火烟雾检测举例)
  • HTML+JS+CSS制作一个数独游戏
  • 原生屏幕旋转算法(AccelSensor)
  • 力扣-31.下一个排列
  • Python打卡:Day47
  • 【排序】插入排序
  • 单调栈通关指南:从力扣 84 到力扣 42
  • eslint扁平化配置
  • IoTDB:专为物联网场景设计的高性能时序数据库
  • 深圳凭物联网软件开发构建智慧‘城市大脑‘
  • c语言学习_函数递归
  • 「Java案例」求n1-n2内的素数
  • 使用Node.js搭建Web应用有哪些注意事项?
  • 在 Vue2 与 Vue3 中,面对 **大数据量交互体验优化** 和 **ECharts 大数据渲染性能优化**
  • 萌新赛第(一)场
  • EfficientVMamba: Atrous Selective Scan for Light Weight Visual Mamba论文精读(逐段解析)
  • 华为泰山服务器重启后出现 XFS 文件系统磁盘“不识别”(无法挂载或访问),但挂载点目录仍在且无数据
  • Nginx完全指南 - 从入门到精通(加强版)
  • 【深度学习入门 鱼书学习笔记(1)感知机】
  • Java常用加密算法详解与实战代码 - 附可直接运行的测试示例
  • Spring Boot 多数据源切换:AbstractRoutingDataSource
  • 语言模型 RLHF 实践指南(一):策略网络、价值网络与 PPO 损失函数
  • MySQL索引面试问题梳理
  • 【Android】组件及布局介绍
  • Flutter基础(前端教程②-卡片列表)
  • 【牛客刷题】小红的v三元组