diff --git a/script/sharding/README.md b/script/sharding/README.md
new file mode 100644
index 0000000..a27513d
--- /dev/null
+++ b/script/sharding/README.md
@@ -0,0 +1,34 @@
+# 分库分表(可选接入)
+
+基于 [Apache ShardingSphere-JDBC](https://shardingsphere.apache.org/) 5.5.3 的可选接入材料。项目默认**不启用**:本目录不是 Maven 模块,不参与默认构建,主工程的依赖、配置、业务表都不受影响。
+
+接入后,`master` 主库保持不变,只有 `@DS("sharding")` 的代码,才通过 ShardingSphereDriver 访问 2 库 × 2 表的示例逻辑表 `demo_sharding_order`。
+
+安装、配置、启动验证及使用限制,请阅读项目文档《分库分表》,本文只列出材料及分支适用范围:
+
+- 单体项目 ruoyi-vue-pro:
+- 微服务项目 yudao-cloud:
+
+## 1. 材料清单
+
+| 文件 | 说明 | 单体项目的目标位置 | 微服务项目的目标位置 |
+| --- | --- | --- | --- |
+| `sql/mysql/demo_sharding_order.sql` | 创建 2 个物理库、4 张物理表 | 在 MySQL 中执行 | 在 MySQL 中执行 |
+| `dependencies.xml` | Maven 依赖片段 | `yudao-server/pom.xml` | 服务的 `pom.xml`,例如 `yudao-module-infra-server/pom.xml` |
+| `dynamic-datasource.yaml` | `sharding` 数据源配置片段 | `yudao-server` 的 `application-{profile}.yaml` | 服务的 `application-{profile}.yaml` 或 Nacos 配置 |
+| `src/main/resources/sharding/sharding.yaml` | ShardingSphere 分片规则 | `yudao-module-infra/src/main/resources` | `yudao-module-infra-server/src/main/resources` |
+| `src/main/java/.../shardingdemo/` | 示例 DO、Mapper、Service | `yudao-module-infra/src/main/java` | `yudao-module-infra-server/src/main/java` |
+
+## 2. 分支适用范围
+
+本目录维护在 `master-jdk17` 分支,`master`、`master-jdk25` 分支通过正常的分支同步获得同一份材料,三个分支的接入步骤相同。按各分支 Spring Boot BOM 管理的依赖版本,接入时的差异如下:
+
+| 分支 | JDK | Spring Boot | 差异 |
+| --- | --- | --- | --- |
+| `master` | 8 | 2.7.18 | 添加 `dependencies.xml` 第 2 段的 SnakeYAML 1.33;不能单独升级到 2.x,原因见该文件的注释 |
+| `master-jdk17` | 17 | 3.5.15 | 添加 `dependencies.xml` 第 3 段的 SnakeYAML 2.7 |
+| `master-jdk25` | 25 | 4.1.2 | 添加 `dependencies.xml` 第 3 段的 SnakeYAML 2.7 |
+
+`dependencies.xml` 的第 2、3 段 SnakeYAML 只能按分支选择其一,不能同时添加。
+
+示例 Java 代码只依赖项目已有的 MyBatis Plus、Dynamic Datasource 和多租户组件,不直接引用 ShardingSphere 的类,三个分支无需修改。
diff --git a/script/sharding/dependencies.xml b/script/sharding/dependencies.xml
new file mode 100644
index 0000000..cd9defc
--- /dev/null
+++ b/script/sharding/dependencies.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ org.apache.shardingsphere
+ shardingsphere-jdbc
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-sharding-core
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-jdbc-dialect-mysql
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-infra-url-classpath
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-standalone-mode-repository-memory
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-infra-data-source-pool-hikari
+ 5.5.3
+
+
+ org.apache.shardingsphere
+ shardingsphere-authority-simple
+ 5.5.3
+
+
+
+
+
+ org.yaml
+ snakeyaml
+ 1.33
+
+
+
+
+
+ org.yaml
+ snakeyaml
+ 2.7
+
+
+
diff --git a/script/sharding/dynamic-datasource.yaml b/script/sharding/dynamic-datasource.yaml
new file mode 100644
index 0000000..9d17ef2
--- /dev/null
+++ b/script/sharding/dynamic-datasource.yaml
@@ -0,0 +1,16 @@
+# 分库分表的 sharding 数据源配置片段,不能直接作为配置文件使用。
+# 将 sharding 合并到已有的 spring.datasource.dynamic.datasource 下,与 master、slave 同级,其它配置保持不变:
+# - 单体项目:yudao-server 的 application-{profile}.yaml
+# - 微服务项目:对应服务(例如说 yudao-module-infra-server)的 application-{profile}.yaml,或者 Nacos 中该服务的配置
+spring:
+ datasource:
+ dynamic:
+ datasource:
+ sharding: # 分库分表数据源,只有 @DS("sharding") 的 Mapper、Service 使用,不影响 master 主库
+ lazy: false # 启动时初始化,规则或数据库有误时尽早失败;也避免在异步线程中首次加载 classpath 规则文件
+ type: com.zaxxer.hikari.HikariDataSource # 不使用 Druid 连接池,ShardingSphere 的逻辑 SQL 不需要 Druid 解析
+ driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
+ url: jdbc:shardingsphere:classpath:sharding/sharding.yaml?placeholder-type=environment # 规则文件中的 $${环境变量名::默认值},从环境变量读取
+ hikari:
+ minimum-idle: 1
+ maximum-pool-size: 10 # 逻辑连接数,不能大于 sharding.yaml 中每个物理库的 maximumPoolSize
diff --git a/script/sharding/sql/mysql/demo_sharding_order.sql b/script/sharding/sql/mysql/demo_sharding_order.sql
new file mode 100644
index 0000000..933a006
--- /dev/null
+++ b/script/sharding/sql/mysql/demo_sharding_order.sql
@@ -0,0 +1,75 @@
+-- ----------------------------
+-- 分库分表示例:2 个物理库 × 每库 2 张物理表,对应逻辑表 demo_sharding_order
+--
+-- 1. 分片规则见 src/main/resources/sharding/sharding.yaml:
+-- 分库:ds_${user_id % 2},分表:demo_sharding_order_${user_id.intdiv(2) % 2}
+-- 2. 本脚本使用「库名.表名」,可以在同一个 MySQL 实例上直接执行;
+-- 如果 ds_0、ds_1 是两个不同的 MySQL 实例,则分别执行对应库的语句
+-- 3. 主键 id 由应用的雪花算法生成,所以不使用 AUTO_INCREMENT
+-- 4. 不要在 master 主库创建同名的 demo_sharding_order 表,避免数据源切换失效时“静默”写入主库
+-- ----------------------------
+
+CREATE DATABASE IF NOT EXISTS `yudao_sharding_0` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+CREATE DATABASE IF NOT EXISTS `yudao_sharding_1` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+-- ----------------------------
+-- ds_0:yudao_sharding_0
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `yudao_sharding_0`.`demo_sharding_order_0` (
+ `id` bigint NOT NULL COMMENT '编号',
+ `user_id` bigint NOT NULL COMMENT '用户编号(分片键)',
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '订单名称',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_user_id` (`user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '分库分表示例订单表';
+
+CREATE TABLE IF NOT EXISTS `yudao_sharding_0`.`demo_sharding_order_1` (
+ `id` bigint NOT NULL COMMENT '编号',
+ `user_id` bigint NOT NULL COMMENT '用户编号(分片键)',
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '订单名称',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_user_id` (`user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '分库分表示例订单表';
+
+-- ----------------------------
+-- ds_1:yudao_sharding_1
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `yudao_sharding_1`.`demo_sharding_order_0` (
+ `id` bigint NOT NULL COMMENT '编号',
+ `user_id` bigint NOT NULL COMMENT '用户编号(分片键)',
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '订单名称',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_user_id` (`user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '分库分表示例订单表';
+
+CREATE TABLE IF NOT EXISTS `yudao_sharding_1`.`demo_sharding_order_1` (
+ `id` bigint NOT NULL COMMENT '编号',
+ `user_id` bigint NOT NULL COMMENT '用户编号(分片键)',
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '订单名称',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE,
+ KEY `idx_user_id` (`user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '分库分表示例订单表';
diff --git a/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderDO.java b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderDO.java
new file mode 100644
index 0000000..884f103
--- /dev/null
+++ b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderDO.java
@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.infra.shardingdemo;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * 分库分表示例订单 DO
+ *
+ * 逻辑表 demo_sharding_order,按 userId 分布到 2 个库 × 每库 2 张表,规则见 sharding/sharding.yaml
+ *
+ * @author 芋道源码
+ */
+@TableName("demo_sharding_order")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DemoShardingOrderDO extends TenantBaseDO {
+
+ /**
+ * 编号
+ *
+ * 分库分表后无法使用数据库自增,由 MyBatis Plus 的雪花算法生成全局唯一编号
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+ /**
+ * 用户编号,即分片键
+ *
+ * 新增时必须有值,创建后不允许修改
+ */
+ private Long userId;
+ /**
+ * 订单名称
+ */
+ private String name;
+
+}
diff --git a/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderMapper.java b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderMapper.java
new file mode 100644
index 0000000..ea348d0
--- /dev/null
+++ b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderMapper.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.infra.shardingdemo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 分库分表示例订单 Mapper
+ *
+ * 在 Mapper 上添加 @DS 注解,保证逻辑表 demo_sharding_order 的 SQL 都使用 sharding 数据源
+ *
+ * @author 芋道源码
+ */
+@Mapper
+@DS(DemoShardingOrderMapper.DATA_SOURCE)
+public interface DemoShardingOrderMapper extends BaseMapperX {
+
+ /**
+ * 分库分表的数据源名,对应 spring.datasource.dynamic.datasource.sharding 配置项
+ */
+ String DATA_SOURCE = "sharding";
+
+ default List selectListByUserId(Long userId) {
+ return selectList(new LambdaQueryWrapperX()
+ .eq(DemoShardingOrderDO::getUserId, userId)
+ .orderByDesc(DemoShardingOrderDO::getId));
+ }
+
+ default PageResult selectPage(PageParam pageParam, Long userId) {
+ return selectPage(pageParam, new LambdaQueryWrapperX()
+ .eqIfPresent(DemoShardingOrderDO::getUserId, userId) // 有 userId 时只查询一个分片,否则查询全部分片后归并
+ .orderByDesc(DemoShardingOrderDO::getId));
+ }
+
+}
diff --git a/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderService.java b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderService.java
new file mode 100644
index 0000000..be963ac
--- /dev/null
+++ b/script/sharding/src/main/java/cn/iocoder/yudao/module/infra/shardingdemo/DemoShardingOrderService.java
@@ -0,0 +1,77 @@
+package cn.iocoder.yudao.module.infra.shardingdemo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
+
+import java.util.List;
+
+/**
+ * 分库分表示例订单 Service
+ *
+ * 1. 带 userId(分片键)的方法,只路由到一个物理库的一张物理表
+ * 2. 不带 userId 的方法,会查询全部 4 个物理节点,再由 ShardingSphere 归并结果
+ *
+ * @author 芋道源码
+ */
+@Service
+@DS(DemoShardingOrderMapper.DATA_SOURCE) // 先切换到 sharding 数据源,再开启 @Transactional 事务
+@RequiredArgsConstructor // 使用构造方法注入,避免 JDK 8 与 JDK 17+ 分支的 @Resource 包名不同
+public class DemoShardingOrderService {
+
+ private final DemoShardingOrderMapper demoShardingOrderMapper;
+
+ @Transactional(rollbackFor = Exception.class) // 同一个 userId 只在一个物理库,所以是单库的本地事务
+ public Long createOrder(Long userId, String name) {
+ Assert.notNull(userId, "用户编号(分片键)不能为空");
+ DemoShardingOrderDO order = DemoShardingOrderDO.builder().userId(userId).name(name).build();
+ demoShardingOrderMapper.insert(order);
+ return order.getId();
+ }
+
+ @Transactional(rollbackFor = Exception.class)
+ public int updateOrderName(Long userId, Long id, String name) {
+ Assert.notNull(userId, "用户编号(分片键)不能为空");
+ // 更新条件带上分片键;更新内容不包含 userId,分片键创建后不允许修改
+ DemoShardingOrderDO updateObj = DemoShardingOrderDO.builder().name(name).build();
+ return demoShardingOrderMapper.update(updateObj, new LambdaQueryWrapperX()
+ .eq(DemoShardingOrderDO::getUserId, userId)
+ .eq(DemoShardingOrderDO::getId, id));
+ }
+
+ @Transactional(rollbackFor = Exception.class)
+ public int deleteOrder(Long userId, Long id) {
+ Assert.notNull(userId, "用户编号(分片键)不能为空");
+ return demoShardingOrderMapper.delete(new LambdaQueryWrapperX()
+ .eq(DemoShardingOrderDO::getUserId, userId)
+ .eq(DemoShardingOrderDO::getId, id));
+ }
+
+ public DemoShardingOrderDO getOrder(Long userId, Long id) {
+ Assert.notNull(userId, "用户编号(分片键)不能为空");
+ return demoShardingOrderMapper.selectOne(DemoShardingOrderDO::getUserId, userId,
+ DemoShardingOrderDO::getId, id);
+ }
+
+ public List getOrderListByUserId(Long userId) {
+ Assert.notNull(userId, "用户编号(分片键)不能为空");
+ return demoShardingOrderMapper.selectListByUserId(userId);
+ }
+
+ /**
+ * 获得订单分页
+ *
+ * @param pageParam 分页参数
+ * @param userId 用户编号,可为空;为空时查询全部分片,页码越大,归并的数据越多
+ * @return 订单分页
+ */
+ public PageResult getOrderPage(PageParam pageParam, Long userId) {
+ return demoShardingOrderMapper.selectPage(pageParam, userId);
+ }
+
+}
diff --git a/script/sharding/src/main/resources/sharding/sharding.yaml b/script/sharding/src/main/resources/sharding/sharding.yaml
new file mode 100644
index 0000000..169b150
--- /dev/null
+++ b/script/sharding/src/main/resources/sharding/sharding.yaml
@@ -0,0 +1,59 @@
+# ShardingSphere-JDBC 5.5.3 分片规则,由 sharding 数据源的 JDBC URL 加载:
+# jdbc:shardingsphere:classpath:sharding/sharding.yaml?placeholder-type=environment
+#
+# 注意:本文件由 ShardingSphere 自己解析,不支持 Spring 的 ${ENV:default} 占位符。
+# 由于 URL 带有 placeholder-type=environment 参数,可以使用 $${环境变量名::默认值} 读取环境变量:
+# 1. 名字与默认值之间的 :: 不能省略,没有默认值时写成 $${环境变量名::}
+# 2. 值会原样替换到本文件中,密码不能包含 $、\、' 字符
+# 3. 不要把真实的账号密码写入本文件、提交到 Git
+
+databaseName: sharding_db # 逻辑库名,只在 ShardingSphere 内部使用
+
+mode:
+ type: Standalone # 单机模式,规则只从本文件加载,不依赖注册中心
+ repository:
+ type: Memory # 元数据保存在内存,不额外创建 H2 等存储
+
+dataSources:
+ ds_0:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl: $${YUDAO_SHARDING_DS0_URL::jdbc:mysql://127.0.0.1:3306/yudao_sharding_0?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true}
+ username: $${YUDAO_SHARDING_DS0_USERNAME::root}
+ password: '$${YUDAO_SHARDING_DS0_PASSWORD::}'
+ minimumIdle: 1
+ maximumPoolSize: 10 # 不能小于 sharding 数据源的 hikari.maximum-pool-size
+ ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl: $${YUDAO_SHARDING_DS1_URL::jdbc:mysql://127.0.0.1:3306/yudao_sharding_1?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true}
+ username: $${YUDAO_SHARDING_DS1_USERNAME::root}
+ password: '$${YUDAO_SHARDING_DS1_PASSWORD::}'
+ minimumIdle: 1
+ maximumPoolSize: 10 # 不能小于 sharding 数据源的 hikari.maximum-pool-size
+
+rules:
+ - !SHARDING
+ tables:
+ demo_sharding_order: # 逻辑表,即 DO 上 @TableName 的表名
+ actualDataNodes: ds_$->{0..1}.demo_sharding_order_$->{0..1} # 2 库 × 2 表,共 4 个物理节点
+ databaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: demo_sharding_order_database_inline
+ tableStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: demo_sharding_order_table_inline
+ shardingAlgorithms:
+ demo_sharding_order_database_inline:
+ type: INLINE
+ props:
+ algorithm-expression: ds_$->{user_id % 2} # 分库:user_id 对 2 取余
+ demo_sharding_order_table_inline:
+ type: INLINE
+ props:
+ algorithm-expression: demo_sharding_order_$->{user_id.intdiv(2) % 2} # 分表:user_id 整除 2 后对 2 取余,与分库错开,4 个节点均匀分布
+
+props:
+ sql-show: false # 设置为 true 时,打印逻辑 SQL 与实际路由的 SQL(包含参数值),仅建议本地排查时开启