Spring Boot集成ShardingSphere实现数据分片(三) | Spring Cloud 42

news2024/11/18 15:35:58

一、前言

在前面我们通过以下章节对数据分片有了基础的了解:

Spring Boot集成ShardingSphere实现数据分片(一) | Spring Cloud 40

Spring Boot集成ShardingSphere实现数据分片(二) | Spring Cloud 41

知道数据分片产生的背景及面临的挑战和其各数据分片类型在业务场景下的优缺,感兴趣的小伙伴自行浏览。

书接上回,本章进行对以下部分进行集成演示:

  • 通过Spring Boot集成ShardingSphere-JDBC来实现数据分片,展示其集成步骤和各注意事项
  • 对分库、分表进行示例展示
  • 展示日常开发使用到的数据分片算法

下面我们开始正文内容。

二、ShardingSphere-JDBC介绍

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。

ShardingSphere-JDBC 定位为轻量级 Java 框架,在 JavaJDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

  • 适用于任何基于 JDBCORM 框架,如:JPAHibernateMybatisSpring JDBC Template 或直接使用 JDBC
  • 支持任何第三方的数据库连接池,如:DBCPC3P0BoneCPHikariCP 等;
  • 支持任意实现 JDBC 规范的数据库,目前支持 MySQLPostgreSQLOracleSQLServer 以及任何可使用 JDBC 访问的数据库。

更多ShardingSphere介绍请见官网:https://shardingsphere.apache.org/document/current/cn/overview/

2.1 核心概念

2.1.1 表

表是透明化数据分片的关键概念。 Apache ShardingSphere 通过提供多样化的表类型,适配不同场景下的数据分片需求。

2.1.1.1 逻辑表

相同结构的水平拆分数据库(表)的逻辑名称,是 SQL 中表的逻辑标识。 例:订单数据根据主键尾数拆分为 10 张表,分别是 t_order_0t_order_9,他们的逻辑表名为 t_order

2.1.1.2 真实表

在水平拆分的数据库中真实存在的物理表。 即上个示例中的 t_order_0t_order_9

2.1.1.3 绑定表

指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时,必须使用分片键进行关联,否则会出现笛卡尔积关联或跨库关联,从而影响查询效率。

例如:t_order 表和 t_order_item 表,均按照 order_id 分片,并且使用 order_id 进行关联,则此两张表互为绑定表关系。 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。 举例说明,如果 SQL 为:

SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

在不配置绑定表关系时,假设分片键 order_id 将数值 10 路由至第 0 片,将数值 11 路由至第 1 片,那么路由后的 SQL 应该为 4 条,它们呈现为笛卡尔积:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

在配置绑定表关系,并且使用 order_id 进行关联后,路由的 SQL 应该为 2 条:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

其中 t_order 表由于指定了分片条件,ShardingSphere 将会以它作为整个绑定表的主表。 所有路由计算将会只使用主表的策略,那么 t_order_item 表的分片计算将会使用 t_order 的条件。

2.1.1.4 广播表

指所有的分片数据源中都存在的表,表结构及其数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

2.1.1.5 单表

指所有的分片数据源中仅唯一存在的表。 适用于数据量不大且无需分片的表。

2.1.2 数据节点

数据分片的最小单元,由数据源名称和真实表组成。 例:ds_0.t_order_0。 逻辑表与真实表的映射关系,可分为均匀分布和自定义分布两种形式。

2.1.2.1 均匀分布

指数据表在每个数据源内呈现均匀分布的态势, 例如:

db0
  ├── t_order0
  └── t_order1
db1
  ├── t_order0
  └── t_order1

数据节点的配置如下:

db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1

2.1.2.2 自定义分布

指数据表呈现有特定规则的分布, 例如:

db0
  ├── t_order0
  └── t_order1
db1
  ├── t_order2
  ├── t_order3
  └── t_order4

数据节点的配置如下:

db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4

2.1.3 分片

2.1.3.1 分片键

用于将数据库(表)水平拆分的数据库字段。

例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。

SQL 中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,Apache ShardingSphere 也支持根据多个字段进行分片。

2.1.3.2 分片算法

用于将数据分片的算法,支持 =、>=、<=、>、<、BETWEENIN 进行分片。 分片算法可由开发者自行实现,也可使用 Apache ShardingSphere 内置的分片算法语法糖,灵活度非常高。

2.1.3.3 自动化分片算法

分片算法语法糖,用于便捷的托管所有数据节点,使用者无需关注真实表的物理分布。 包括取模、哈希、范围、时间等常用分片算法的实现。

2.1.3.4 自定义分片算法

提供接口让应用开发者自行实现与业务实现紧密相关的分片算法,并允许使用者自行管理真实表的物理分布。 自定义分片算法又分为:

  • 标准分片算法

    用于处理使用单一键作为分片键的 =、IN、BETWEEN AND、>、<、>=、<= 进行分片的场景。

  • 复合分片算法

    用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。

  • Hint 分片算法

    用于处理使用 Hint 行分片的场景。

2.1.3.5 分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。 真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。

2.1.3.6 强制分片路由

对于分片字段并非由 SQL 而是其他外置条件决定的场景,可使用 SQL Hint 注入分片值。

例:按照员工登录主键分库,而数据库中并无此字段。 SQL Hint 支持通过 Java APISQL 注释两种方式使用。 详情请参见强制分片路由。

2.1.4 行表达式

行表达式是为了解决配置的简化与一体化这两个主要问题。

在繁琐的数据分片规则配置中,随着数据节点的增多,大量的重复配置使得配置本身不易被维护。 通过行表达式可以有效地简化数据节点配置工作量。

对于常见的分片算法,使用 Java 代码实现并不有助于配置的统一管理。 通过行表达式书写分片算法,可以有效地将规则配置一同存放,更加易于浏览与存储。

行表达式的使用非常直观,只需要在配置中使用 ${ expression }$->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。 行表达式的内容使用的是 Groovy 的语法,Groovy 能够支持的所有操作,行表达式均能够支持。 例如:

${begin..end} 表示范围区间 ${[unit1, unit2, unit_x]} 表示枚举值

行表达式中如果出现连续多个 ${ expression }$->{ expression } 表达式,整个表达式最终的结果将会根据每个子表达式的结果进行笛卡尔组合。

例如,以下行表达式:

${['online', 'offline']}_table${1..3}

最终会解析为:

online_table1, online_table2, online_table3, offline_table1, offline_table2, offline_table3

2.1.5 分布式主键

传统数据库软件开发中,主键自动生成技术是基本需求。而各个数据库对于该需求也提供了相应的支持,比如 MySQL 的自增键,Oracle 的自增序列等。

数据分片后,不同数据节点生成全局唯一主键是非常棘手的问题。同一个逻辑表内的不同实际表之间的自增键由于无法互相感知而产生重复主键。 虽然可通过约束自增主键初始值和步长的方式避免碰撞,但需引入额外的运维规则,使解决方案缺乏完整性和可扩展性。

目前有许多第三方解决方案可以完美解决这个问题,如 UUID 等依靠特定算法自生成不重复键,或者通过引入主键生成服务等。

为了方便用户使用、满足不同用户不同使用场景的需求, Apache ShardingSphere 不仅提供了内置的分布式主键生成器,例如 UUIDSNOWFLAKE,还抽离出分布式主键生成器的接口,方便用户自行实现自定义的自增主键生成器。

三、分库分表示例

3.1 分库分表总体结构

3.1.1 数据源ds1

数据库地址数据源名称真实表名逻辑表名称业务描述
192.168.0.35ds1t_goods_0t_goods商品表-分库/分表
192.168.0.35ds1t_goods_1t_goods商品表-分库/分表
192.168.0.35ds1t_order_0t_order订单表-分库/分表
192.168.0.35ds1t_order_1t_order订单表-分库/分表
192.168.0.35ds1t_order_item_0t_order_item订单明细表-分库/分表
192.168.0.35ds1t_order_item_1t_order_item订单明细表-分库/分表
192.168.0.35ds1sys_dictsys_dict系统字典表-单表
192.168.0.35ds1sys_dict_itemsys_dict_item系统字典子表-单表

3.1.1 数据源ds2

数据库地址数据源名称真实表名逻辑表名称业务描述
192.168.0.46ds2t_goods_0t_goods商品表-分库/分表
192.168.0.46ds2t_goods_1t_goods商品表-分库/分表
192.168.0.46ds2t_order_0t_order订单表-分库/分表
192.168.0.46ds2t_order_1t_order订单表-分库/分表
192.168.0.46ds2t_order_item_0t_order_item订单明细表-分库/分表
192.168.0.46ds2t_order_item_1t_order_item订单明细表-分库/分表
192.168.0.46ds2sys_dictsys_dict系统字典表-单表
192.168.0.46ds2sys_dict_itemsys_dict_item系统字典子表-单表

3.1.1 逻辑商品表 t_goods

-- ----------------------------
-- Table structure for t_goods_0
-- ----------------------------
DROP TABLE IF EXISTS `t_goods_0`;
CREATE TABLE `t_goods_0`  (
  `goods_id` bigint NOT NULL,
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `main_class` bigint NULL DEFAULT NULL COMMENT '商品大类数据字典',
  `sub_class` bigint NULL DEFAULT NULL COMMENT '商品小类数据字典',
  PRIMARY KEY (`goods_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_goods_1
-- ----------------------------
DROP TABLE IF EXISTS `t_goods_1`;
CREATE TABLE `t_goods_1`  (
  `goods_id` bigint NOT NULL,
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `main_class` bigint NULL DEFAULT NULL COMMENT '商品大类数据字典',
  `sub_class` bigint NULL DEFAULT NULL COMMENT '商品小类数据字典',
  PRIMARY KEY (`goods_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

3.1.2 逻辑订单表 t_order

-- ----------------------------
-- Table structure for t_order_0
-- ----------------------------
DROP TABLE IF EXISTS `t_order_0`;
CREATE TABLE `t_order_0`  (
  `order_id` bigint NOT NULL AUTO_INCREMENT,
  `create_by` bigint NULL DEFAULT NULL COMMENT '下单人',
  `create_time` datetime NULL DEFAULT NULL COMMENT '下单时间',
  PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_order_1
-- ----------------------------
DROP TABLE IF EXISTS `t_order_1`;
CREATE TABLE `t_order_1`  (
  `order_id` bigint NOT NULL AUTO_INCREMENT,
  `create_by` bigint NULL DEFAULT NULL COMMENT '下单人',
  `create_time` datetime NULL DEFAULT NULL COMMENT '下单时间',
  PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

3.1.3 逻辑订单明细表

-- ----------------------------
-- Table structure for t_order_item_0
-- ----------------------------
DROP TABLE IF EXISTS `t_order_item_0`;
CREATE TABLE `t_order_item_0`  (
  `order_item_id` bigint NOT NULL AUTO_INCREMENT,
  `order_id` bigint NOT NULL,
  `goods_id` bigint NOT NULL COMMENT '商品ID',
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `create_by` bigint NULL DEFAULT NULL COMMENT '下单人',
  `create_time` datetime NULL DEFAULT NULL COMMENT '下单时间',
  PRIMARY KEY (`order_item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_order_item_1
-- ----------------------------
DROP TABLE IF EXISTS `t_order_item_1`;
CREATE TABLE `t_order_item_1`  (
  `order_item_id` bigint NOT NULL AUTO_INCREMENT,
  `order_id` bigint NOT NULL,
  `goods_id` bigint NOT NULL COMMENT '商品ID',
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `create_by` bigint NULL DEFAULT NULL COMMENT '下单人',
  `create_time` datetime NULL DEFAULT NULL COMMENT '下单时间',
  PRIMARY KEY (`order_item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

3.1.4 系统字典表

DROP TABLE IF EXISTS `sys_dict`;
CREATE TABLE `sys_dict`  (
  `id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '字典ID',
  `dict_code` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典代码',
  `dict_name` varchar(125) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典名称',
  `dict_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '字典状态\r\n0: 停用\r\n1: 启用',
  `dict_type` tinyint(4) NULL DEFAULT 0 COMMENT '字典类型(0-系统字典 5-公共 9-解析字典)',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `idx`(`dict_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-字典表' ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `sys_dict_item`;
CREATE TABLE `sys_dict_item`  (
  `id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '字典子项id',
  `dict_id` bigint(18) NOT NULL COMMENT '字典ID',
  `dict_item_code` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典子项代码',
  `dict_item_value` varchar(125) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典子项展示值',
  `dict_item_desc` varchar(125) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '字典子项描述',
  `item_status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '字典子项状态\r\n0: 停用\r\n1: 启用',
  `item_attrs` varchar(1024) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '自定义json字符串属性',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统-字典子项表' ROW_FORMAT = Dynamic;

3.2 项目结构

3.2.1 项目总体结构

在这里插入图片描述

3.2.2 Maven 依赖

shading-sphere/shading-databases-tables/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>shading-sphere</artifactId>
        <groupId>com.gm</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shading-databases-tables</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.2.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.25</version>
        </dependency>

    </dependencies>

</project>
  • shardingsphere-jdbc-core-spring-boot-starter使用版本5.2.1
  • JDBCORM 框架选用mybatis-plus

3.2.3 配置文件

shading-sphere/shading-databases-tables/src/main/resources/application.yml

server:
  port: 8844

spring:
  application:
    name: @artifactId@
  shardingsphere:
    # 数据源配置
    datasource:
      names: ds1,ds2
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.35:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'
      ds2:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.46:3306/db2?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'

    # 定义规则
    rules:
      sharding:
        # 数据分片规则配置
        tables:
          # 指定某个表的分片配置,逻辑表名,此商品表按照大类进行分库,按照小类进行分表
          t_goods:
            # 这个配置是告诉sharding有多少个库和多少个表及所在实际的数据库节点,由数据源名 + 表名组成(参考 Inline 语法规则)
            actual-data-nodes: ds$->{1..2}.t_goods_$->{0..1}
            # 配置库分片策略
            database-strategy:
              # 用于单分片键的标准分片场景
              standard:
                # 分片列名称
                sharding-column: main_class
                # 分片算法名称
                sharding-algorithm-name: t_goods_database_inline
            # 配置表分片策略
            table-strategy:
              # 用于单分片键的标准分片场景
              standard:
                # 分片列名称
                sharding-column: sub_class
                # 分片算法名称
                sharding-algorithm-name: t_goods_table_inline
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: goods_id
              # 分布式序列算法名称
              key-generator-name: snowflake
          # 指定某个表的分片配置,逻辑表名,此订单表缺省分库策略表示使用默认分库策略,按照订单ID进行分表
          t_order:
            # 这个配置是告诉sharding有多少个库和多少个表及所在实际的数据库节点,由数据源名 + 表名组成(参考 Inline 语法规则)
            actual-data-nodes: ds$->{1..2}.t_order_$->{0..1}
            # 配置表分片策略
            table-strategy:
              # 用于单分片键的标准分片场景
              standard:
                # 分片列名称
                sharding-column: order_id
                # 分片算法名称
                sharding-algorithm-name: t_order_table_inline
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
          # 指定某个表的分片配置,逻辑表名,此订单明细表缺省分库策略表示使用默认分库策略,按照订单ID进行分表
          t_order_item:
            # 这个配置是告诉sharding有多少个库和多少个表及所在实际的数据库节点,由数据源名 + 表名组成(参考 Inline 语法规则)
            actual-data-nodes: ds$->{1..2}.t_order_item_$->{0..1}
            # 配置表分片策略
            table-strategy:
              # 用于单分片键的标准分片场景
              standard:
                # 分片列名称
                sharding-column: order_id
                # 分片算法名称
                sharding-algorithm-name: t_order_order_item_inline
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_item_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 分片算法名称
          t_goods_table_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: t_goods_${sub_class % 2}
          # 分片算法名称
          t_goods_database_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: ds$->{main_class % 2 + 1}
          # 分片算法名称
          t_order_table_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: t_order_${order_id % 2}
          # 分片算法名称
          t_order_order_item_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: t_order_item_${order_id % 2}
          # 分片算法名称
          default_database_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: ds$->{create_by % 2 + 1}
        # 分布式序列算法配置(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
        keyGenerators:
          # 分布式序列算法名称
          snowflake:
            # 分布式序列算法类型
            type: SNOWFLAKE
        # 绑定表规则列表
        binding-tables:
          - t_goods
          - t_order_item
        broadcast-tables:
          - sys_dict,sys_dict_item
        # 默认数据库分片策略,当分库策略缺省表示使用默认分库策略
        defaultDatabaseStrategy:
          # 用于单分片键的标准分片场景
          standard:
            # 分片列名称
            sharding-column: create_by
            # 分片算法名称
            sharding-algorithm-name: default_database_inline
    props:
      sql-show: true #显示sql

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置简要说明:

  • 商品逻辑表t_goods
    • 按照商品大类取模分片算法进行分库
    • 按照商品小类取模分片算法进行分表
  • 订单逻辑表t_order
    • 按照下单人取模分片算法进行分库
    • 按照订单ID取模分片算法进行分表
  • 订单明细逻辑表t_order_item
    • 按照下单人取模分片算法进行分库
    • 按照订单ID取模分片算法进行分表
  • 广播表: t_goodst_order_item
  • 真实表: sys_dictsys_dict_item
  • 分布式序列:采用雪花算法(针对分布式序列,在插入数据的sql中就不要传对应列名,null也不行)

更多配置项详解:https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/sharding/

更多分片算法详解:https://shardingsphere.apache.org/document/current/cn/dev-manual/sharding/

完整源码可见:https://gitee.com/gm19900510/springboot-cloud-example.git

后续介绍定义的分片算法的使用。

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

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

相关文章

Sentinel --- 简介、流量控制

一、Sentinel 1.1、雪崩问题及解决方案 雪崩问题 微服务中&#xff0c;服务间调用关系错综复杂&#xff0c;一个微服务往往依赖于多个其它微服务。 如图&#xff0c;如果服务提供者I发生了故障&#xff0c;当前的应用的部分业务因为依赖于服务I&#xff0c;因此也会被阻塞。此…

Spring AOP(重点、难点)

Spring AOP&#xff08;重点、难点&#xff09; 文章目录 Spring AOP&#xff08;重点、难点&#xff09;1.aop引入1.1 使用场景与概念引入1.2 以数据校验记录操作日志为例 写一组代码进行递推初始阶段 老老实实一个一个写&#xff1a;阶段一 **将日志和验证方法包装到一个类里…

海洋测绘设备使用总结快讯(2023年5月)

本文主要记录最近海洋测绘设备使用过程中遇到一些小问题和解决方法。 1、侧扫声纳绞车的事情 从去年10月到今年3月一直有一个困扰我们的问题&#xff1a;我们侧扫声纳的铠装缆在租用广西北海渔船且用发电机发电的情况下&#xff0c;能连接Klein3000和Klein4000拖鱼&#xff0…

通过Date类学习面向对象

通过手撸这个类的实现&#xff0c;我们可以学习到构造、析构、运算符重载&#xff0c;拷贝构造等面向对象中重要的知识。 首先先看头文件中类的定义&#xff1a; class Date { public:// 获取某年某月的天数int GetMonthDay(int year, int month);// 全缺省的构造函数Date(in…

算法的时间复杂度和空间复杂度(友友们专属限定版)

&#x1f349;博客主页&#xff1a;阿博历练记 &#x1f4d6;文章专栏&#xff1a;数据结构与算法 &#x1f69a;代码仓库&#xff1a;阿博编程日记 &#x1f339;欢迎关注&#xff1a;欢迎友友们点赞收藏关注哦 文章目录 &#x1f3a8;1.算法的复杂度介绍&#x1f3a8;2.时间复…

坤强服务器安装

记录一下服务器安装做raid和安装系统 raid 0 拆分开分别存在3块硬盘,一块坏了,全部不能用了, 但是存储速度最快 raid 1 具有最高的安全性,备份一份,容量只有总容量的一半 raid 10 先组两个raid1,再组两个raid0 .有raid 1的安全性和50%的使用容量 raid 5 安全性&#xff…

汇编二、51单片机内部结构

1、单片机内部资源 以AT89C51单片机为例&#xff0c;参考数据手册。 Atmel官网&#xff1a; https://www.microchip.com/ (1)1个8位CPU。 (2)4K ROM&#xff0c;128字节RAM。 (3)32个GPIO&#xff1b;定时器(Timer)&#xff1b;串口(UART)&#xff1b;中断系统(Interrupt…

Qt之滑动条和进度条(QSlider、QProgressBar)

文章目录 前言一、QSliderQSlider的常用API信号与槽 二、QProgressBar滑动条和滚动条的常用API 总结 前言 在用户界面设计中&#xff0c;滑动条和进度条是常见的控件。Qt中提供了QProgressBar和QSlider两个类来实现滚动条和滑动条。 一、QSlider 在Qt中&#xff0c;QSlider是…

ChatGPT攥写广告文案-写好广告营销软文的必备要点

chatgpt帮助我们写营销软文 Chat GPT是一款强大的自然语言处理模型&#xff0c;可以辅助您编写优秀的营销软文。下面是几个使用 Chat GPT 更好的编写营销软文的建议&#xff1a; 利用Chat GPT自动摘要 Chat GPT能够将一段较长的营销文本精简成几个关键点&#xff0c;这有利于…

32. 最长有效括号

32. 最长有效括号 难度困难2251 给你一个只包含 ( 和 ) 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 1&#xff1a; 输入&#xff1a;s "(()" 输出&#xff1a;2 解释&#xff1a;最长有效括号子串是 "…

《C语言技术体系》 学习路线总目录 + 思维导图

目录 前言 正文 思维导图 第1章 流程结构 1.1 初识C语言 1.2 流程结构 1.3 数据类型 1.4 运算符表达式 第2章 指针与数组 2.1 指针基本概念 2.2 一维数组 2.3 二维及多维数组 2.4 指针与数组 第3章 模块化重构 3.1 函数 3.2 typedef类型定义 3.3 enum枚举 3.…

手把手教你使用vue2搭建微前端micro-app

​ 简述 本文主要讲述新手小白怎么搭建micro-app&#xff0c;几乎是每一步都有截图说明。上手应该很简单。 本来我之前已经写了一篇手把手教程了&#xff0c;但是当时写的结个太乱了&#xff0c;趁着五一休假&#xff0c;重新整理了一番&#xff0c;加了文章目录&#xff0c;…

如何显示文件夹的后缀和隐藏文件

© Ptw-cwl 文章目录 前言文件夹后缀隐藏文件 如何设置显示文件夹的后缀和隐藏文件 前言 文件夹后缀 文件后缀是指文件名中最后一个“.”后面的一串字符&#xff0c;用来表示该文件的类型或格式。不同的文件类型有不同的后缀&#xff0c;例如&#xff0c;常见的图片文件…

对象浅拷贝的5种方式

参考原文:浅拷贝的五种实现方式 - 掘金 (juejin.cn) 哈喽 大家好啊 最近发现自己对对象都不是很熟练&#xff0c;特别是涉及到一些复制&#xff0c;深浅拷贝的东西 1.Object.assign 首先 我们创建一个空对象obj1 然后创建一个对象obj2 用object.assign(目标对象&#xff0c…

庖丁解牛函数知识---C语言《2》

目录 前言&#xff1a; 1.嵌套调用函数 2.链式访问 3.函数的声明与定义 4.*递归 5.递归与非递归 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&#xff0c;C生万物&#xff01; 开始我们的C语言之旅吧…

C6678学习-GPIO

文章目录 1、简介2、框图3、寄存器4、地址 1、简介 C6678中共有16个GPIO&#xff0c;GPIO0~GPIO15。这些引脚的功能如下 ​ 通用输入输出管脚​ 中断&EDMA事件管脚 2、框图 1、GPIO作为通用输入输出时&#xff0c;用到的寄存器为DIR、SET_DATA、OUT_DATA、CLR_DATA、IN_…

AI奇点已至,是黎明前的黑暗,还是黑夜前的黄昏

2022年11月&#xff0c;OPEN AI公司推出了ChatGPT 3模型&#xff0c;瞬间引爆全球话题&#xff0c;所有业内人士都在感叹他的强大&#xff0c;比尔盖茨也曾经评价道&#xff0c;ChatGPT将会改变世界 &#xff0c;是一个相当于PC和互联网的革命性产品。 作为信息行业人&#xff…

网络请求与远程资源

网络请求与远程资源 网络分层 一、OSI七层模型、TCP/IP概念层模型 区别&#xff1a;OSI模型注重通信协议必要的功能是什么&#xff0c;TCP/IP模型更强调在计算机上实现协议应该开发哪种程序。 二、应用层的网络协议 FTP&#xff1a;文本传输协议SMTP&#xff1a;简单邮件传输协…

简单理解什么是序列化

为什么要序列化 序列化的目的就是为了对象可以在网络层进行传输&#xff0c; 比如通过后端传给前端数据。 什么是序列化 我们以Java为例。 序列化就是把对象转化为可传输的字节序列过程&#xff0c;这个字节序列可以是字符串&#xff0c;比如JSON格式的字符串&#xff0c;把…

基于海洋捕食者算法的极限学习机(ELM)回归预测-附代码

基于海洋捕食者算法的极限学习机(ELM)回归预测 文章目录 基于海洋捕食者算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于海洋捕食者算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用海洋捕食者算法对极限学习…