ShardingJDBC 排除不需要分库分表的表配置指南

95 阅读3分钟

ShardingJDBC 排除不需要分库分表的表配置指南

在使用ShardingJDBC进行分库分表时,我们经常会遇到需要排除某些表,使其不参与分库分表的情况。下面详细介绍不同版本的配置方法。

一、不同版本的处理方式

1. ShardingJDBC 5.x 版本

ShardingJDBC 5.x 版本简化了配置,不需要额外配置,框架会自动识别:

  • 未在分片规则中配置的表将被自动识别为不需要分库分表的表
  • 系统会自动路由到适当的数据源

2. ShardingJDBC 3.x 和 4.x 版本

对于这两个版本,有两种主要方法来处理不需要分库分表的表:

二、方法一:配置默认数据源(推荐)

通过配置 default-data-source,可以让未在分片规则中配置的表自动路由到默认数据源。

1. YAML 配置示例

spring:
  shardingsphere:
    # 数据源配置
    datasource:
      names: db0,db1,ds-default
      # 分片数据源1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db0?serverTimezone=UTC
        username: root
        password: 123456
      # 分片数据源2
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
        username: root
        password: 123456
      # 默认数据源(用于存储不需要分库分表的表)
      ds-default:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/default_db?serverTimezone=UTC
        username: root
        password: 123456
    
    # 分片规则配置
    sharding:
      # 设置默认数据源
      default-data-source-name: ds-default
      
      # 只配置需要分片的表
      tables:
        t_order:
          actual-data-nodes: db$->{0..1}.t_order_$->{0..1}
          table-strategy:
            inline:
              sharding-column: order_id
              algorithm-expression: t_order_$->{order_id % 2}

2. 工作原理

  • 需要分库分表的表:在 tables 下明确配置分片规则
  • 不需要分库分表的表:不配置在 tables 中,ShardingJDBC 会自动将其路由到 default-data-source-name 指定的数据源

三、方法二:使用多个独立数据源

将分片数据源和非分片数据源分开配置,在应用中根据需要使用不同的数据源。

1. 配置示例

# 分片数据源配置
spring:
  shardingsphere:
    datasource:
      names: db0,db1
      # 分片数据源配置...
    sharding:
      tables:
        # 分片表配置...

# 非分片数据源配置
non-sharding:
  datasource:
    url: jdbc:mysql://localhost:3306/default_db?serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

2. 配置类实现

@Configuration
public class DataSourceConfig {
    
    // ShardingJDBC 数据源配置
    @Bean(name = "shardingDataSource")
    @ConfigurationProperties(prefix = "spring.shardingsphere")
    public DataSource shardingDataSource() throws SQLException {
        return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), 
            new ShardingRuleConfiguration(), new Properties());
    }
    
    // 非分片数据源配置
    @Bean(name = "nonShardingDataSource")
    @ConfigurationProperties(prefix = "non-sharding.datasource")
    public DataSource nonShardingDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    // 数据源路由配置
    @Bean
    public DataSource routingDataSource(@Qualifier("shardingDataSource") DataSource shardingDataSource,
                                       @Qualifier("nonShardingDataSource") DataSource nonShardingDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("sharding", shardingDataSource);
        targetDataSources.put("nonSharding", nonShardingDataSource);
        
        AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                // 根据ThreadLocal中的标识决定使用哪个数据源
                return DataSourceContextHolder.getDataSourceKey();
            }
        };
        
        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(shardingDataSource);
        return routingDataSource;
    }
}

3. 使用方式

// 切换到非分片数据源
DataSourceContextHolder.setDataSourceKey("nonSharding");
// 执行非分片表操作
userService.selectAll();
// 切换回分片数据源
DataSourceContextHolder.setDataSourceKey("sharding");

四、对单表的简单配置方式

对于3.x和4.x版本,如果不需要分库分表的表数量不多,也可以为每个表单独配置固定的数据源:

spring:
  shardingsphere:
    sharding:
      tables:
        # 需要分库分表的表
        t_order:
          # 分片配置...
        
        # 不需要分库分表的表,直接指定数据源
        t_user:
          actual-data-nodes: db0.t_user
        t_dict:
          actual-data-nodes: db0.t_dict

五、注意事项

  1. 版本差异:5.x版本配置更简单,自动识别非分片表;3.x/4.x版本需要显式配置

  2. 默认数据源选择

    • 建议创建专门的默认数据源存放非分片表
    • 也可以使用现有的某个分片数据源作为默认数据源
  3. 性能考量

    • 使用默认数据源方式配置简单,对代码无侵入性
    • 多数据源方式更灵活,但需要在代码中手动切换数据源
  4. 事务一致性:跨数据源的操作需要考虑分布式事务问题

  5. 5.x版本迁移:如果从低版本升级到5.x,需要注意配置方式的变化

通过上述配置方法,可以灵活地管理需要分库分表的表和不需要分库分表的表,满足不同业务场景的需求。