ShardingSphere实战(3)- 快速实现分库分表

上篇博客,我们讲了 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_ordert_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

总结:本篇博客实现了水平分库分表,后续会陆续更新广播表默认表路由读写分离

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值