SpringBoot3分库分表

打印 上一主题 下一主题

主题 942|帖子 942|积分 2826

标签:ShardingSphere5.分库.分表;
一、简介

分库分表的设计和实现方式,在之前的内容中总结过很多,本文基于SpringBoot3和ShardingSphere5框架实现数据分库分表的能力;
不得不提ShardingSphere5文档中描述的两个基本概念:

垂直分片
按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。
水平分片
水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。
下面从案例实践中,看看ShardingSphere5框架是如何实现分库分表的原理;
二、工程搭建

1、工程结构


2、依赖管理

这里只看两个核心组件的依赖:shardingsphere-jdbc组件是5.2.1版本,mybatis组件是3.5.13版本,在依赖管理中还涉及MySQL和分页等,并且需要添加很多排除配置,具体见源码;
  1. <dependency>
  2.     <groupId>org.mybatis.spring.boot</groupId>
  3.     <artifactId>mybatis-spring-boot-starter</artifactId>
  4.     <version>${mybatis.version}</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>org.apache.shardingsphere</groupId>
  8.     <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
  9.     <version>${shardingsphere.version}</version>
  10. </dependency>
复制代码
三、配置详解

1、配置文件

此处只展示分库分表的相关配值,默认数据源使用db_master库,注意tb_order库表路由的策略和分片算法的关联关系,其他工程配置详见源码仓库;
  1. spring:
  2.   # 分库分表配置
  3.   shardingsphere:
  4.     datasource:
  5.       # 默认数据源
  6.       sharding:
  7.         default-data-source-name: db_master
  8.       names: db_master,db_0,db_1
  9.       db_master:
  10.         type: com.zaxxer.hikari.HikariDataSource
  11.         driver-class-name: com.mysql.cj.jdbc.Driver
  12.         jdbc-url: jdbc:mysql://localhost:3306/shard_db
  13.         username: root
  14.         password: 123456
  15.       db_0:
  16.         type: com.zaxxer.hikari.HikariDataSource
  17.         driver-class-name: com.mysql.cj.jdbc.Driver
  18.         jdbc-url: jdbc:mysql://localhost:3306/shard_db_0
  19.         username: root
  20.         password: 123456
  21.       db_1:
  22.         type: com.zaxxer.hikari.HikariDataSource
  23.         driver-class-name: com.mysql.cj.jdbc.Driver
  24.         jdbc-url: jdbc:mysql://localhost:3306/shard_db_1
  25.         username: root
  26.         password: 123456
  27.     rules:
  28.       sharding:
  29.         tables:
  30.           # tb_order逻辑
  31.           tb_order:
  32.             actual-data-nodes: db_${0..1}.tb_order_${0..2}
  33.             # tb_order库路由
  34.             database-strategy:
  35.               standard:
  36.                 sharding-column: order_id
  37.                 sharding-algorithm-name: database_inline
  38.             # tb_order表路由
  39.             table-strategy:
  40.               standard:
  41.                 sharding-column: order_id
  42.                 sharding-algorithm-name: table_inline
  43.         sharding-algorithms:
  44.           # tb_order库路由算法
  45.           database_inline:
  46.             type: INLINE
  47.             props:
  48.               algorithm-expression: db_${order_id % 2}
  49.           # tb_order表路由算法
  50.           table_inline:
  51.             type: INLINE
  52.             props:
  53.               algorithm-expression: tb_order_${order_id % 3}
  54.     props:
  55.       sql-show: true
  56.       sql-comment-parse-enabled: true
复制代码
2、配置原理

在配置中需要管理三个数据源,shard_db默认库,在操作不涉及需要路由的表时默认使用该数据源,shard_db_0和shard_db_1是tb_order逻辑表的路由库;

逻辑表tb_order整体使用两个数据库,每个库建3张结构相同相同的表,在操作tb_order数据时,会根据order_id字段值定位数据所属的分片节点;

  • 库路由db_${0..1}采用db_${order_id%2}的算法;
  • 表路由tb_order_${0..2}采用tb_order_${order_id%3}的算法;
四、测试案例

1、主库操作

基于Mybatis持久层框架,实现对shard_db默认库的数据操作,注意控制台的日志打印,可以看到一系列解析逻辑以及库表节点的定位,分页查询使用PageHelper组件即可;
  1. public class MasterTest {
  2.     @Autowired
  3.     private BuyerMapper buyerMapper ;
  4.     @Autowired
  5.     private SellerMapper sellerMapper ;
  6.     @Test
  7.     public void testBuyerQuery (){
  8.         // 主键查询
  9.         Buyer buyer = buyerMapper.selectByPrimaryKey(1) ;
  10.         System.out.println(buyer.getId()+";"+buyer.getBuyerName());
  11.     }
  12.     @Test
  13.     public void testBuyerInsert (){
  14.         // 新增数据
  15.         Buyer buyer = new Buyer() ;
  16.         buyer.setBuyerName("买家Three");
  17.         System.out.println(buyerMapper.insert(buyer));
  18.     }
  19.     @Test
  20.     public void testBuyerUpdate (){
  21.         // 更新数据
  22.         Buyer buyer = buyerMapper.selectByPrimaryKey(3) ;
  23.         if (buyer != null){
  24.             buyer.setBuyerName("Three买家");
  25.             System.out.println(buyerMapper.updateByPrimaryKey(buyer));
  26.         }
  27.     }
  28.     @Test
  29.     public void testSellerPage (){
  30.         // 1、设置分页和查询条件
  31.         PageHelper.startPage(2,2) ;
  32.         SellerExample sellerExample = new SellerExample() ;
  33.         sellerExample.setOrderByClause("id asc");
  34.         // 2、查询数据
  35.         List<Seller> sellerList = sellerMapper.selectByExample(sellerExample) ;
  36.         // 3、构建分页实体对象
  37.         PageInfo<Seller> pageInfo = new PageInfo<>(sellerList) ;
  38.         System.out.println(pageInfo);
  39.     }
  40. }
复制代码
2、分库操作

在对tb_order表执行增删改查时,会根据order_id的字段值计算库表的路由节点,注意分页时会查询所有的分库和分表,然后汇总查询的结果;
[code]public class ShardTest {    @Autowired    private OrderMapper orderMapper ;    /**     * 写入100条数据     */    @Test    public void testOrderInsert (){        for (int i=1 ; i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表