上篇博客,我们讲了 ShardingSphere实战(2)- 水平分表 ,这篇博客,我们继续实现分库以及解决前面遗留的问题。
一、绑定表
基于上篇博客配置的前提下(上篇博客的最后放上了完整的配置,需要的可以去看看,这里就不重复写上去了),加上绑定表
的配置:
# 绑定表关系
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
1. 查询数据
/**
* 多个表水平分表测试-查询
*/
@GetMapping("/test4")
public String test4(@RequestParam("orderId") Long orderId) {
List<OrderItemExtDO> orderDO = orderMapper.findOrderAndOrderItemsByOrderId(orderId);
log.info("orderDO: {}", orderDO.toString());
return "success";
}
<select id="findOrderAndOrderItemsByOrderId" resultType="com.shardingsphere.demo.dal.entity.OrderItemExtDO">
select t1.order_id t1OrderId,
t1.order_no orderNo,
t2.order_id t2OrderId
from t_order t1
inner join t_order_item t2 on t1.order_id = t2.order_id
where t1.order_id = #{orderId,jdbcType=BIGINT}
</select>
2. 对比结果
配置绑定表关系之前:
取的是笛卡尔积
配置绑定表关系之后:
3. 绑定表总结
绑定表是指那些经常一起使用的表,例如在联表查询中同时出现的订单表 t_order
和订单详情表 t_order_item
。ShardingSphere 会将 t_order
和 t_order_item
视为一组绑定表,在执行 SQL 查询时,如果涉及到这两张表,ShardingSphere 会确保它们的数据分布在相同的分片上,从而避免跨库的复杂联表查询,提高查询效率。
绑定表的原理
- 数据一致性:绑定表的数据会在同一个数据库分片中,保证了数据的一致性和完整性。
- 查询优化:避免了跨库的联表查询,减少了网络延迟和查询时间。
配置注意事项
- 表名顺序:在
binding-tables
配置中,表名的顺序很重要,通常主表(如 t_order)放在前面,从表(如 t_order_item)放在后面。 - 关联字段:绑定表通常通过一个共同的字段(如订单ID)关联,这个字段需要在所有绑定表中存在且类型一致。
- 分片策略:确保绑定表使用相同的分片策略,这样它们才能被正确地分配到同一个分片上。
二、水平分库
1. 创建数据库
create database ds-0;
create database ds-1;
# 分别在ds-0和ds-1中创建下面的表
create table t_order_0
(
order_id bigint not null
primary key,
order_no varchar(100) null,
create_name varchar(50) null,
price decimal(10, 2) null
)
create table t_order_1
(
order_id bigint not null
primary key,
order_no varchar(100) null,
create_name varchar(50) null,
price decimal(10, 2) null
)
create table t_order_2
(
order_id bigint not null
primary key,
order_no varchar(100) null,
create_name varchar(50) null,
price decimal(10, 2) null
)
create table t_order_item_0
(
order_item_id bigint not null
primary key,
item_id bigint null,
order_id bigint null,
item_name varchar(50) null,
price decimal(10, 2) null
)
create table t_order_item_1
(
order_item_id bigint not null
primary key,
item_id bigint null,
order_id bigint null,
item_name varchar(50) null,
price decimal(10, 2) null
)
create table t_order_item_2
(
order_item_id bigint not null
primary key,
item_id bigint null,
order_id bigint null,
item_name varchar(50) null,
price decimal(10, 2) null
)
2. 配置分片策略
基于上一篇博客的分片策略,做一些修改:
# sharding-jdbc 水平分表策略
# 给数据源起别名,这里名称需要和下面的一致
spring.shardingsphere.datasource.names=ds-0,ds-1
# 配置数据源
spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://xxx:3316/ds-0?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds-0.username=xxx
spring.shardingsphere.datasource.ds-0.password=xxx
spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://xxx:3316/ds-1?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds-1.username=xxx
spring.shardingsphere.datasource.ds-1.password=xxx
####################### 配置分片表t_order #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds-$->{0..1}.t_order_$->{0..2}
### 分库策略
# 分库分片健
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=order_id
# 分库分片算法
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds-$->{order_id % 2}
### 分表策略
# 分表分片健
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分表算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 3}
####################### 配置分片表t_order_item #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds-$->{0..1}.t_order_item_$->{0..2}
### 分库策略
# 分库分片健
spring.shardingsphere.sharding.tables.t_order_item.database-strategy.inline.sharding-column=order_id
# 分库分片算法
spring.shardingsphere.sharding.tables.t_order_item.database-strategy.inline.algorithm-expression=ds-$->{order_id % 2}
### 分表策略
# 分表分片健
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
# 分表算法
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 3}
# 绑定表关系
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
# 是否开启 SQL解析日志
spring.shardingsphere.props.sql.show=true
mybatis.mapper-locations=classpath:sqlmapper/*.xml
3. 保存测试
/**
* 多个表水平分库分表测试-保存
*/
@GetMapping("/test3")
public String test3(@RequestParam("count") Integer count) {
for (int i = 0; i < count; i++) {
OrderDO order = new OrderDO();
order.setOrderId(this.getId());
order.setOrderNo("A" + order.getOrderId());
order.setCreateName("订单 " + order.getOrderId());
orderMapper.insertSelective(order);
OrderItemDO orderItem = new OrderItemDO();
orderItem.setOrderItemId(order.getOrderId());
orderItem.setOrderId(order.getOrderId());
orderItemMapper.insertSelective(orderItem);
}
return "success";
}
运行结果:
4. 单表查询测试
/**
* 单个表水平分表测试-查询
*/
@GetMapping("/test2")
public String test2(@RequestParam("orderId") Long orderId) {
OrderDO orderDO = orderMapper.selectByPrimaryKey(orderId);
log.info("orderDO: {}", orderDO.toString());
return "success";
}
运行结果:
5. 绑定表查询测试
上面有绑定表的测试代码,这里就不重复写了,和上面一样,直接看运行结果:
结果也没问题,没有跨库跨表查询
三、完整配置
老规矩,下面是本篇博客关于ShardingSphere
的完整配置:
# sharding-jdbc 水平分表策略
# 给数据源起别名,这里名称需要和下面的一致
spring.shardingsphere.datasource.names=ds-0,ds-1
# 配置数据源
spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://xxx:3316/ds-0?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds-0.username=xxx
spring.shardingsphere.datasource.ds-0.password=xxx
spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://xxx:3316/ds-1?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds-1.username=xxx
spring.shardingsphere.datasource.ds-1.password=xxx
####################### 配置分片表t_order #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds-$->{0..1}.t_order_$->{0..2}
### 分库策略
# 分库分片健
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=order_id
# 分库分片算法
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds-$->{order_id % 2}
### 分表策略
# 分表分片健
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分表算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 3}
####################### 配置分片表t_order_item #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds-$->{0..1}.t_order_item_$->{0..2}
### 分库策略
# 分库分片健
spring.shardingsphere.sharding.tables.t_order_item.database-strategy.inline.sharding-column=order_id
# 分库分片算法
spring.shardingsphere.sharding.tables.t_order_item.database-strategy.inline.algorithm-expression=ds-$->{order_id % 2}
### 分表策略
# 分表分片健
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
# 分表算法
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 3}
# 绑定表关系
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
# 是否开启 SQL解析日志
spring.shardingsphere.props.sql.show=true
mybatis.mapper-locations=classpath:sqlmapper/*.xml
总结:本篇博客实现了水平分库分表
,后续会陆续更新广播表
、默认表路由
、读写分离
等
下一篇:ShardingSphere实战(4)- 广播表和默认数据源
标签:分库,spring,ShardingSphere,id,ds,item,shardingsphere,分表,order From: https://blog.csdn.net/java_liuyuan/article/details/140823406