Sharding-JDBC系列(七):Sharding-JDBC 分库分表实践

此系列文章都是基于 Sharding-JDBC 4.x版本, 在写此文章时,正式发布的是 4.1.0版本,点此 4.x 官方文档

一个应用如果业务高速增长,产生大量的数据,单数据库的性能可能难以满足业务快速增长的需求,此时就可以考虑采用分库来分担单个数据库的压力,提高系统的性能。

本篇基于 Spring Boot + Mybatis + Mybatis-Plus 集成 Sharding-JDBC 实现分库分表示例。

分库分表配置

数据分片配置示例 及 配置项说明 可参考 [Sharding-JDBC系列(三):Sharding-JDBC分片配置示例与说明](http://www.gxitsky.com/article/5] 中关于 Spring Boot 环境的配置。

分库分表实践

准备库表

1
2
3
4
5
6
7
8
9
10
-- 建库,创建 2 个数据库:order0, order1
CREATE DATABASE `order0` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- 建表,创建 4 个订单表:order_info_0,order_info_1,order_info_2,order_info_3
CREATE TABLE `order_info_0` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`org_code` VARCHAR(32) DEFAULT NULL COMMENT '机构编码',
`order_no` VARCHAR(32) DEFAULT NULL COMMENT '订单号',
`user_id` BIGINT(20) DEFAULT NULL COMMENT '用户ID',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

添加依赖

创建 Spring Boot 项目,添加相关依赖。

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gxitsky</groupId>
<artifactId>sharding-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sharding-jdbc-table</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除logback,后面配置log4j2 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<!--start:jdbc-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>org.inurl.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

配置文件

主配置文件

application.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
spring.profiles.active=sharding_db_table_inline
spring.application.name=sharding-jdbc
#server.servlet.context-path=/sharding/table

#============Spring MVC=================
##======throw ex for 404 code, close static resource mapping=======
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

#============MyBatis ===================
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
mybatis-plus.type-aliases-package=com.gxitsky.shardingjdbc.table.entity
mybatis-plus.configuration.map-underscore-to-camel-case=true

#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#===========Jackson======================
spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.default-property-inclusion=non_empty

分库分表配置文件

下面是基于 Spring Boot 的 properties 配置文件,使用行表达式配置分库分表。

  • 根据机构编码(org_code % 2)分 2 个库。
  • 根据用户ID(user_id % 4)分 4 个表

application-sharding_db_table_inline.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#=============ShardingSphere Datasource=================

#------------System Config-----------------------------
spring.shardingsphere.props.sql.show=true
spring.shardingsphere.props.sql.simple=true

#-------------Data Source Config------------------------
spring.shardingsphere.datasource.names=ds0,ds1
#spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
#spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:log4jdbc:mysql://localhost:3306/order?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.shardingsphere.datasource.ds0.url=jdbc:log4jdbc:mysql://localhost:3306/order0?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.shardingsphere.datasource.ds1.url=jdbc:log4jdbc:mysql://localhost:3306/order1?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
#------可以使用默认的分库策略,也可为为指定表的分库策略--------
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=org_code
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{org_code % 2}
spring.shardingsphere.sharding.tables.order_info.actual-data-nodes=ds$->{0..1}.order_info_$->{0..3}
spring.shardingsphere.sharding.tables.order_info.database-strategy.inline.sharding-column=org_code
spring.shardingsphere.sharding.tables.order_info.database-strategy.inline.algorithm-expression=ds$->{org_code % 2}
spring.shardingsphere.sharding.tables.order_info.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.order_info.table-strategy.inline.algorithm-expression=order_info_$->{user_id % 4}

业务代码

Entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Data
@Accessors(chain = true)
@TableName(value = "order_info")
public class OrderInfo implements Serializable {
private static final long serialVersionUID = 7228334740131864851L;

/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 机构编码
*/
private Integer orgCode;
/**
* 订单号
*/
private String orderNo;
/**
* 用户ID
*/
private Long userId;

public OrderInfo() {
}

public OrderInfo(String orderNo, Long userId) {
this.orderNo = orderNo;
this.userId = userId;
}

public OrderInfo(Integer orgCode, String orderNo, Long userId) {
this.orgCode = orgCode;
this.orderNo = orderNo;
this.userId = userId;
}
}

Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@RestController
@RequestMapping("/order")
public class OrderController {
private static final Logger logger = LogManager.getLogger(OrderController.class);

@Autowired
private OrderService orderService;

/**
* @desc: 单个用户的订单列表
*/
@GetMapping("/list")
public List<OrderInfo> listByOrgCodeAndUserId(Long userId, Integer orgCode) {
return orderService.listByOrgCodeAndUserId(userId, orgCode);
}

/**
* @desc: 添加订单
*/
@PostMapping("/save")
public int save(Long userId, Integer orgCode) {
return orderService.save(userId, orgCode);
}
}

Service

OrderService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @desc 订单接口
*/
public interface OrderService {
/**
* @desc: listByOrgCodeAndUserId
* @param: [userId, orgCode]
*/
List<OrderInfo> listByOrgCodeAndUserId(Long userId, Integer orgCode);

/**
* @desc: save
* @param: [userId, orgCode]
*/
int save(Long userId, Integer orgCode);

}

OrderServiceImpl

通过orgCode分库,userId分表,查询、插入、更新、删除的条件就必须包含这 2 个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @desc 订单服务
*/
@Service
public class OrderServiceImpl implements OrderService {

@Autowired
private OrderMapper orderMapper;

@Override
public List<OrderInfo> listByOrgCodeAndUserId(Long userId, Integer orgCode) {
LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderInfo::getUserId, userId)
.eq(OrderInfo::getOrgCode, orgCode);
return orderMapper.selectList(queryWrapper);
}

@Override
public int save(Long userId, Integer orgCode) {
Long millis = System.currentTimeMillis();
return orderMapper.insert(new OrderInfo(orgCode, String.valueOf(millis), userId));
}
}

Mapper

1
2
3
4
5
6
/**
* @desc 订单Mapper
*/
@Repository
public interface OrderMapper extends BaseMapper<OrderInfo> {
}

日志分析

插入数据

请求:

两个请求,路由到 2 个数据库 和 对应的分表

1
2
localhost:8080/order/save?userId=1001&orgCode=1
localhost:8080/order/save?userId=1002&orgCode=2

日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 第1个请求生成的逻辑SQL
2020-09-30 14:16:57,699 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 14:16:57,699 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@1747b301, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@66175c00), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@66175c00, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[1, 1601446617661, 1001])], generatedKeyContext=Optional.empty)
# 第1个请求的真实SQL, orgCode 1 % 2 = 1, 路由到 ds1 数据源; userId 1001 % 4 = 1 路由到 order_info_1 分表
2020-09-30 14:16:57,699 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] Actual SQL(simple): [ds1] ::: 1
2020-09-30 14:16:57,703 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-6] INSERT INTO order_info_1 ( org_code, order_no, user_id ) VALUES (1, '1601446617661', 1001)

2020-09-30 14:16:57,775 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-6]
|--------------|
|generated_key |
|--------------|
|3 |
|--------------|

# 第2个请求生成的逻辑SQL
2020-09-30 14:17:46,005 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 14:17:46,005 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@1747b301, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@158c2d5e), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@158c2d5e, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[2, 1601446666003, 1002])], generatedKeyContext=Optional.empty)
# 第2个请求的真实SQL, orgCode 2 % 2 = 0, 路由到 ds0 数据源; userId 1002 % 4 = 2 路由到 order_info_2 分表
2020-09-30 14:17:46,006 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] Actual SQL(simple): [ds0] ::: 1
2020-09-30 14:17:46,007 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-7] INSERT INTO order_info_2 ( org_code, order_no, user_id ) VALUES (2, '1601446666003', 1002)

2020-09-30 14:17:46,111 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-7]
|--------------|
|generated_key |
|--------------|
|3 |
|--------------|

自定义标准分片策略

自定义标准分片策略,验证分库的范围分片,创建 3 个数据库 order0,order1,order2。

分库分表配置

Spring Boot 主配置文件 application.properites 中设置激活引配置文件。

1
spring.profiles.active=sharding_db_table_standard

application-sharding_db_table_standard.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#=============ShardingSphere Datasource=================

#------------System Config-----------------------------
spring.shardingsphere.props.sql.show=true
spring.shardingsphere.props.sql.simple=true

#-------------Data Source Config------------------------
spring.shardingsphere.datasource.names=ds0,ds1,ds2
#spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
#spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:log4jdbc:mysql://localhost:3306/order?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.shardingsphere.datasource.ds0.url=jdbc:log4jdbc:mysql://localhost:3306/order0?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.shardingsphere.datasource.ds1.url=jdbc:log4jdbc:mysql://localhost:3306/order1?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456

spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds2.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.shardingsphere.datasource.ds2.url=jdbc:log4jdbc:mysql://localhost:3306/order2?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
spring.shardingsphere.datasource.ds2.username=root
spring.shardingsphere.datasource.ds2.password=123456

#可以使用default-database-strategy
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=org_code
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{org_code % 2}
spring.shardingsphere.sharding.tables.order_info.actual-data-nodes=ds$->{0..1}.order_info_$->{0..3}
spring.shardingsphere.sharding.tables.order_info.database-strategy.standard.sharding-column=org_code
spring.shardingsphere.sharding.tables.order_info.database-strategy.standard.preciseAlgorithmClassName=com.gxitsky.shardingjdbc.table.common.config.OrgCodeShardingAlgorithm
spring.shardingsphere.sharding.tables.order_info.database-strategy.standard.rangeAlgorithmClassName=com.gxitsky.shardingjdbc.table.common.config.OrgCodeShardingAlgorithm
spring.shardingsphere.sharding.tables.order_info.table-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.order_info.table-strategy.standard.preciseAlgorithmClassName=com.gxitsky.shardingjdbc.table.common.config.UserIdShardingAlgorithm
spring.shardingsphere.sharding.tables.order_info.table-strategy.standard.rangeAlgorithmClassName=com.gxitsky.shardingjdbc.table.common.config.UserIdShardingAlgorithm

分库算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* @desc 分库算法, 根据 orgCode % 3 分库,路由到 order0, order1, order2库
*/
@Component
public class OrgCodeShardingAlgorithm implements PreciseShardingAlgorithm<Integer>, RangeShardingAlgorithm<Integer> {
private static final Logger logger = LogManager.getLogger(UserIdShardingAlgorithm.class);
// 数据源前缀
private static final String DATA_SOURCE_PREFIX = "ds";
// 分3个库
private static final int DATABASES = 3;
// 数据源后缀列表
private static List<String> SUFFIX_LIST = new ArrayList<>();

static {
for (int i = 0; i < DATABASES; i++) {
SUFFIX_LIST.add(String.valueOf(i));
}
}

@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> preciseShardingValue) {
logger.info("----->availableTargetNames:{}", JSON.toJSONString(availableTargetNames));
logger.info("----->preciseShardingValue:{}", JSON.toJSONString(preciseShardingValue));

Integer orgCode = preciseShardingValue.getValue();
int num = orgCode % DATABASES;
return DATA_SOURCE_PREFIX + num;
}

@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> rangeShardingValue) {
logger.info("----->availableTargetNames:{}", JSON.toJSONString(availableTargetNames));
logger.info("----->rangeShardingValue:{}", JSON.toJSONString(rangeShardingValue));

Range<Integer> range = rangeShardingValue.getValueRange();
logger.info("----->range lowerEndpoint:{}", range.hasLowerBound() ? range.lowerEndpoint() : null);
logger.info("----->range upperEndpoint:{}", range.hasUpperBound() ? range.upperEndpoint() : null);

if (range.hasLowerBound() && range.hasUpperBound()) {
List<String> indexList = new ArrayList<>();
for (int orgCode = range.lowerEndpoint(); orgCode <= range.upperEndpoint(); orgCode++) {
int num = orgCode % DATABASES;
indexList.add(String.valueOf(num));
}
return indexList.stream().map(index -> DATA_SOURCE_PREFIX + index).collect(Collectors.toList());
}
return SUFFIX_LIST.stream().map(index -> DATA_SOURCE_PREFIX + index).collect(Collectors.toList());
}
}

分表算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* @desc 分表算法, 根据userId分片算法 hash(userId) % 4
* PreciseShardingAlgorithm(精准分片), RangeShardingAlgorithm(范围分片)
*/
@Component
public class UserIdShardingAlgorithm implements PreciseShardingAlgorithm<Long>, RangeShardingAlgorithm<Long> {
private static final Logger logger = LogManager.getLogger(UserIdShardingAlgorithm.class);

private static final int TABLES = 4;
private static List<String> SUFFIX_LIST = new ArrayList<>();

static {
for (int i = 0; i < TABLES; i++) {
SUFFIX_LIST.add(String.valueOf(i));
}
}

@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> preciseShardingValue) {
logger.info("----->availableTargetNames:{}", JSON.toJSONString(availableTargetNames));
logger.info("----->preciseShardingValue:{}", JSON.toJSONString(preciseShardingValue));

String logicTableName = preciseShardingValue.getLogicTableName();
Long userId = preciseShardingValue.getValue();
String index = hashCodeIndex(userId);
return logicTableName + "_" + index;
}

@Override
public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> rangeShardingValue) {
logger.info("----->availableTargetNames:{}", JSON.toJSONString(availableTargetNames));
logger.info("----->rangeShardingValue:{}", JSON.toJSONString(rangeShardingValue));

String logicTableName = rangeShardingValue.getLogicTableName();
Range<Long> range = rangeShardingValue.getValueRange();
logger.info("----->range lowerEndpoint:{}", range.hasLowerBound() ? range.lowerEndpoint() : null);
logger.info("----->range upperEndpoint:{}", range.hasUpperBound() ? range.upperEndpoint() : null);

if (range.hasLowerBound() && range.hasUpperBound()) {
List<String> indexList = new ArrayList<>();
for (Long userId = range.lowerEndpoint(); userId <= range.upperEndpoint(); userId++) {
String index = this.hashCodeIndex(userId);
indexList.add(index);
}
return indexList.stream().map(index -> logicTableName + "_" + index).collect(Collectors.toList());
}
return SUFFIX_LIST.stream().map(index -> logicTableName + "_" + index).collect(Collectors.toList());
}

/**
* @desc: 哈希取模
* @param: [userId]
*/
private String hashCodeIndex(Long userId) {
int index = (userId.hashCode()) % TABLES;
return String.valueOf(index);
}
}

插入数据

4 个请求,orgCode 分别目 1,2,3,期望路由到 ds0, ds1, ds2 数据源,和对应的分表。

1
2
3
4
localhost:8080/order/save?userId=1001&orgCode=1
localhost:8080/order/save?userId=1002&orgCode=2
localhost:8080/order/save?userId=1003&orgCode=3
localhost:8080/order/save?userId=1004&orgCode=3

日志分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
2020-09-30 16:25:40,416 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-10] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:25:40,417 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-10] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":1}
2020-09-30 16:25:40,417 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-10] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:25:40,417 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-10] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1001}
# 逻辑SQL
2020-09-30 16:25:40,418 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-10] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 16:25:40,418 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-10] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@753e89cc, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@1a12caa7), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@1a12caa7, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[1, 1601454340414, 1001])], generatedKeyContext=Optional.empty)
# 真实SQL, orgCode 1 % 3 = 1, userId 1001 % 4 = 1 路由到 ds1 数据源的 order_info_1 表
2020-09-30 16:25:40,418 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-10] Actual SQL(simple): [ds1] ::: 1
2020-09-30 16:25:40,419 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-10] INSERT INTO order_info_1 ( org_code, order_no, user_id ) VALUES (1, '1601454340414', 1001)

2020-09-30 16:25:40,511 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-10]
|--------------|
|generated_key |
|--------------|
|2 |
|--------------|

2020-09-30 16:25:44,988 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-1] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:25:44,989 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-1] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":2}
2020-09-30 16:25:44,989 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:25:44,990 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-1] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1002}
2020-09-30 16:25:44,990 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 16:25:44,990 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@753e89cc, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@60efec13), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@60efec13, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[2, 1601454344986, 1002])], generatedKeyContext=Optional.empty)
# 真实SQL, orgCode 2 % 3 = 2, userId 1002 % 4 = 2 路由到 ds2 数据源的 order_info_2 表
2020-09-30 16:25:44,991 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Actual SQL(simple): [ds2] ::: 1
2020-09-30 16:25:45,006 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] INSERT INTO order_info_2 ( org_code, order_no, user_id ) VALUES (2, '1601454344986', 1002)

2020-09-30 16:25:45,086 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|--------------|
|generated_key |
|--------------|
|2 |
|--------------|

2020-09-30 16:25:51,312 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-2] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:25:51,312 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-2] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":3}
2020-09-30 16:25:51,313 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-2] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:25:51,313 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-2] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1003}
2020-09-30 16:25:51,313 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-2] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 16:25:51,314 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-2] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@753e89cc, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7e580cae), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7e580cae, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[3, 1601454351309, 1003])], generatedKeyContext=Optional.empty)
# 真实SQL, orgCode 3 % 3 = 0, userId 1003 % 4 = 3 路由到 ds0 数据源的 order_info_3 表
2020-09-30 16:25:51,314 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-2] Actual SQL(simple): [ds0] ::: 1
2020-09-30 16:25:51,332 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-2] INSERT INTO order_info_3 ( org_code, order_no, user_id ) VALUES (3, '1601454351309', 1003)

2020-09-30 16:25:51,428 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-2]
|--------------|
|generated_key |
|--------------|
|1 |
|--------------|

2020-09-30 16:25:54,237 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-3] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:25:54,237 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-3] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":3}
2020-09-30 16:25:54,237 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-3] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:25:54,238 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-3] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1004}
2020-09-30 16:25:54,238 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-3] Logic SQL: INSERT INTO order_info ( org_code,
order_no,
user_id ) VALUES ( ?,
?,
? )
2020-09-30 16:25:54,238 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-3] SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@753e89cc, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7221ba89), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7221ba89, columnNames=[org_code, order_no, user_id], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=70, stopIndex=70, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=73, stopIndex=73, parameterMarkerIndex=2)], parameters=[3, 1601454354227, 1004])], generatedKeyContext=Optional.empty)
# 真实SQL, orgCode 4 % 3 = 1, userId 1004 % 4 = 0 路由到 ds1 数据源的 order_info_0 表
2020-09-30 16:25:54,238 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-3] Actual SQL(simple): [ds0] ::: 1
2020-09-30 16:25:54,239 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-3] INSERT INTO order_info_0 ( org_code, order_no, user_id ) VALUES (3, '1601454354227', 1004)

2020-09-30 16:25:54,319 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-3]
|--------------|
|generated_key |
|--------------|
|1 |
|--------------|

查询数据

精准查询的路由与插入的一致。

1
2
3
4
localhost:8080/order/list?userId=1001&orgCode=1
localhost:8080/order/list?userId=1002&orgCode=2
localhost:8080/order/list?userId=1003&orgCode=3
localhost:8080/order/list?userId=1004&orgCode=4

日志分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 3 个数据源
2020-09-30 16:33:14,535 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-6] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:33:14,536 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-6] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":1}
2020-09-30 16:33:14,536 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-6] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:33:14,537 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-6] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1001}
2020-09-30 16:33:14,537 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] Logic SQL: SELECT id,org_code,order_no,user_id FROM order_info

WHERE (user_id = ? AND org_code = ?)
2020-09-30 16:33:14,538 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@432f0017, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@270ca474), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@270ca474, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=35, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=org_code, alias=Optional.empty), ColumnProjection(owner=null, name=order_no, alias=Optional.empty), ColumnProjection(owner=null, name=user_id, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@7d83651c, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@20f9be0a, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@63e7a40c, containsSubquery=false)
# orgCode 1 % 3 = 1 > ds1, 1001 % 4 = 1 > order_info_1
2020-09-30 16:33:14,538 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-6] Actual SQL(simple): [ds1] ::: 1
2020-09-30 16:33:14,539 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-6] SELECT id,org_code,order_no,user_id FROM order_info_1 WHERE (user_id = 1001 AND org_code = 1)

2020-09-30 16:33:14,551 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-6]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |1 |1601454329857 |1001 |
|2 |1 |1601454340414 |1001 |
|---|---------|--------------|--------|

2020-09-30 16:33:21,381 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-7] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:33:21,382 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-7] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":2}
2020-09-30 16:33:21,382 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-7] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:33:21,382 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-7] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1002}
2020-09-30 16:33:21,383 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] Logic SQL: SELECT id,org_code,order_no,user_id FROM order_info

WHERE (user_id = ? AND org_code = ?)
2020-09-30 16:33:21,383 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@432f0017, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7353a895), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7353a895, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=35, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=org_code, alias=Optional.empty), ColumnProjection(owner=null, name=order_no, alias=Optional.empty), ColumnProjection(owner=null, name=user_id, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@5c799f7a, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@60ee83b0, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@a782a9a, containsSubquery=false)
# orgCode 1 % 3 = 2 > ds2, 1002 % 4 = 2 > order_info_2
2020-09-30 16:33:21,384 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-7] Actual SQL(simple): [ds2] ::: 1
2020-09-30 16:33:21,384 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-7] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (user_id = 1002 AND org_code = 2)

2020-09-30 16:33:21,387 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-7]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |2 |1601450086542 |1002 |
|2 |2 |1601454344986 |1002 |
|---|---------|--------------|--------|

2020-09-30 16:33:36,549 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:41] [http-nio-8080-exec-8] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:33:36,549 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:42] [http-nio-8080-exec-8] ----->preciseShardingValue:{"columnName":"org_code","logicTableName":"order_info","value":3}
2020-09-30 16:33:36,549 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:39] [http-nio-8080-exec-8] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:33:36,550 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:40] [http-nio-8080-exec-8] ----->preciseShardingValue:{"columnName":"user_id","logicTableName":"order_info","value":1003}
2020-09-30 16:33:36,551 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-8] Logic SQL: SELECT id,org_code,order_no,user_id FROM order_info

WHERE (user_id = ? AND org_code = ?)
2020-09-30 16:33:36,551 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-8] SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@432f0017, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e869856), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e869856, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=35, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=org_code, alias=Optional.empty), ColumnProjection(owner=null, name=order_no, alias=Optional.empty), ColumnProjection(owner=null, name=user_id, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@24a789f2, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@513b7bcb, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@2663503d, ontainsSubquery=false)
# orgCode 3 % 3 = 0 > ds0, 1003 % 4 = 2 > order_info_3
2020-09-30 16:33:36,551 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-8] Actual SQL(simple): [ds0] ::: 1
2020-09-30 16:33:36,553 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-8] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (user_id = 1003 AND org_code =
3)

2020-09-30 16:33:36,555 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-8]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601454351309 |1003 |
|---|---------|--------------|--------|

范围查询

1
2
3
4
5
6
7
8
@Override
public List<OrderInfo> geByOrgCode(Long userId, Integer orgCode) {
LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.ge(OrderInfo::getOrgCode, orgCode).ge(OrderInfo::getUserId, userId);
// queryWrapper.between(OrderInfo::getOrgCode, orgCode, orgCode + 1)
// .between(OrderInfo::getUserId, userId, userId + 1);
return orderMapper.selectList(queryWrapper);
}

闭区间查询日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

2020-09-30 16:52:20,821 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 16:52:20,837 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:52] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"org_code","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 16:52:20,838 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:2
2020-09-30 16:52:20,838 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:56] [http-nio-8080-exec-1] ----->range upperEndpoint:3
2020-09-30 16:52:20,839 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:50] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:52:20,839 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"user_id","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 16:52:20,839 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:1002
2020-09-30 16:52:20,839 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:56] [http-nio-8080-exec-1] ----->range upperEndpoint:1003
2020-09-30 16:52:20,840 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:50] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 16:52:20,840 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"user_id","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 16:52:20,840 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:1002
2020-09-30 16:52:20,841 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:56] [http-nio-8080-exec-1] ----->range upperEndpoint:1003
2020-09-30 16:52:20,861 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Logic SQL: SELECT id,org_code,order_no,user_id FROM order_info

WHERE (org_code BETWEEN ? AND ? AND user_id BETWEEN ? AND ?)
2020-09-30 16:52:20,862 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@136516ef, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e240523), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e240523, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=35, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=org_code, alias=Optional.empty), ColumnProjection(owner=null, name=order_no, alias=Optional.empty), ColumnProjection(owner=null, name=user_id, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@5289cd9f, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@5df716eb, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@669ea1d4, containsSubquery=false)
# 真实SQL,闭区间,分片算法列出所有可能的数据源 和 分表
# (org_code BETWEEN 2 AND 3) > ds0, ds1
# (user_id BETWEEN 1002 AND 1003) > order_info_2, order_info_3
2020-09-30 16:52:20,862 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Actual SQL(simple): [ds0, ds2] ::: 4
2020-09-30 16:52:20,884 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (org_code BETWEEN 2 AND 3 AND user_id BETWEEN 1002 AND 1003)

2020-09-30 16:52:20,884 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (org_code BETWEEN 2 AND 3 AND user_id BETWEEN 1002 AND 1003)

2020-09-30 16:52:20,903 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (org_code BETWEEN 2 AND 3 AND user_id BETWEEN 1002 AND 1003)

2020-09-30 16:52:20,903 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (org_code BETWEEN 2 AND 3 AND user_id BETWEEN 1002 AND 1003)

2020-09-30 16:52:20,923 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601450089336 |1002 |
|---|---------|--------------|--------|

2020-09-30 16:52:20,924 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601454351309 |1003 |
|---|---------|--------------|--------|

2020-09-30 16:52:20,925 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |2 |1601450086542 |1002 |
|2 |2 |1601454344986 |1002 |
|---|---------|--------------|--------|

2020-09-30 16:52:20,926 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

开区间查询日志

开区间查询会遍历所有数据源的所有分表,即在所有数据源和所有分表上执行相同的一条SQL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

2020-09-30 17:03:05,453 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->availableTargetNames:["ds0","ds1","ds2"]
2020-09-30 17:03:05,470 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:52] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"org_code","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 17:03:05,470 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:2
2020-09-30 17:03:05,471 INFO [LogId:] [c.g.s.t.c.c.OrgCodeShardingAlgorithm->doSharding:56] [http-nio-8080-exec-1] ----->range upperEndpoint:null
2020-09-30 17:03:05,471 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:50] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 17:03:05,471 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"user_id","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 17:03:05,472 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:1002, upperEndpoint:null
2020-09-30 17:03:05,472 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:50] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 17:03:05,472 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"user_id","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 17:03:05,473 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:1002, upperEndpoint:null
2020-09-30 17:03:05,473 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:50] [http-nio-8080-exec-1] ----->availableTargetNames:["order_info_0","order_info_1","order_info_2","order_info_3"]
2020-09-30 17:03:05,473 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:51] [http-nio-8080-exec-1] ----->rangeShardingValue:{"columnName":"user_id","logicTableName":"order_info","valueRange":{"empty":false}}
2020-09-30 17:03:05,473 INFO [LogId:] [c.g.s.t.c.c.UserIdShardingAlgorithm->doSharding:55] [http-nio-8080-exec-1] ----->range lowerEndpoint:1002, upperEndpoint:null
2020-09-30 17:03:05,496 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Logic SQL: SELECT id,org_code,order_no,user_id FROM order_info

WHERE (org_code >= ? AND user_id >= ?)
2020-09-30 17:03:05,496 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@151f7edd, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7e904804), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@7e904804, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=35, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=org_code, alias=Optional.empty), ColumnProjection(owner=null, name=order_no, alias=Optional.empty), ColumnProjection(owner=null, name=user_id, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@3c998baf, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@27cae595, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@494d9e27, containsSubquery=false)
2020-09-30 17:03:05,497 INFO [LogId:] [o.a.s.u.e.l.SQLLogger->log:74] [http-nio-8080-exec-1] Actual SQL(simple): [ds0, ds2, ds1] ::: 12
2020-09-30 17:03:05,515 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_0 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,515 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-1] SELECT id,org_code,order_no,user_id FROM order_info_0 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,515 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_0 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,516 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_1 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,517 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_1 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,517 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-1] SELECT id,org_code,order_no,user_id FROM order_info_1 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,517 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,518 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-1] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,518 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_2 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,518 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-0] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,519 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [ShardingSphere-1] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,519 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->sqlOccurred:228] [http-nio-8080-exec-1] SELECT id,org_code,order_no,user_id FROM order_info_3 WHERE (org_code >= 2 AND user_id >= 1002)

2020-09-30 17:03:05,536 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601454354227 |1004 |
|---|---------|--------------|--------|

2020-09-30 17:03:05,536 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,537 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601450089336 |1002 |
|---|---------|--------------|--------|

2020-09-30 17:03:05,537 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |3 |1601454351309 |1003 |
|---|---------|--------------|--------|

2020-09-30 17:03:05,538 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,538 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,539 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,539 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,539 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,540 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

2020-09-30 17:03:05,540 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|--------------|--------|
|id |org_code |order_no |user_id |
|---|---------|--------------|--------|
|1 |2 |1601450086542 |1002 |
|2 |2 |1601454344986 |1002 |
|---|---------|--------------|--------|

2020-09-30 17:03:05,541 INFO [LogId:] [n.s.l.l.s.Slf4jSpyLogDelegator->resultSetCollected:610] [http-nio-8080-exec-1]
|---|---------|---------|--------|
|id |org_code |order_no |user_id |
|---|---------|---------|--------|
|---|---------|---------|--------|

Sharding-JDBC系列(七):Sharding-JDBC 分库分表实践

http://blog.gxitsky.com/2020/09/29/sharding-jdbc-7-db-table-sharding/

作者

光星

发布于

2020-09-29

更新于

2021-02-05

许可协议

评论