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
五、注意事项
-
版本差异:5.x版本配置更简单,自动识别非分片表;3.x/4.x版本需要显式配置
-
默认数据源选择:
- 建议创建专门的默认数据源存放非分片表
- 也可以使用现有的某个分片数据源作为默认数据源
-
性能考量:
- 使用默认数据源方式配置简单,对代码无侵入性
- 多数据源方式更灵活,但需要在代码中手动切换数据源
-
事务一致性:跨数据源的操作需要考虑分布式事务问题
-
5.x版本迁移:如果从低版本升级到5.x,需要注意配置方式的变化
通过上述配置方法,可以灵活地管理需要分库分表的表和不需要分库分表的表,满足不同业务场景的需求。