首页 > 其他分享 >ShardingSphere实战(3)- 快速实现分库分表

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

时间:2024-08-02 17:54:24浏览次数:22  
标签:分库 spring ShardingSphere id ds item shardingsphere 分表 order

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

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

下一篇:ShardingSphere实战(4)- 广播表和默认数据源

标签:分库,spring,ShardingSphere,id,ds,item,shardingsphere,分表,order
From: https://blog.csdn.net/java_liuyuan/article/details/140823406

相关文章

  • 使用Redisson和分库分表技术实现海量请求注册功能
    文章目录1.海量注册的常见问题和解决方案概述2.布隆过滤器判断用户唯一性3.通过分布式锁和快速失败策略对同一时间的某一个账号进行锁定4.数据库唯一索引兜底5.通过水平分库水平分表配置分片规则6.通过自定义线程池和异步初始化配置线程池操作异步化1.海量......
  • 数据库系列: 主流分库分表中间件介绍(图文总结)
    相关文章数据库系列:MySQL慢查询分析和性能优化数据库系列:MySQL索引优化总结(综合版)数据库系列:高并发下的数据字段变更数据库系列:覆盖索引和规避回表数据库系列:数据库高可用及无损扩容数据库系列:使用高区分度索引列提升性能数据库系列:前缀索引和索引长度的取舍数据库系列:My......
  • 深入理解MyCAT分库分表机制:架构师的秘密武器
    一、MyCAT分库和分表的概念1.分库(DatabaseSharding)分库是将一个大数据库拆分成多个小数据库,以减小单个数据库的压力并提高系统的扩展性。每个子数据库可以分布在不同的服务器上,从而分散负载并提高性能。示例:假设我们有一个用户信息数据库users_db,其中包含了大量的用......
  • 面试官:聊聊你对分库分表的理解?
    在MySQL集群架构中有两种主流的集群实现,一种是读写分离,而另外一种则是数据分片。所谓的数据分片其实就是今天要聊的分库分表技术。分库分表技术不但是日常工作中用于解决数据库中的数据量会急剧增长,解决单库单表性能瓶颈的一种方案,更是面试中的高频知识点。在阿里巴巴的《Java......
  • [Mysql]分库分表
    分库分表读写分离主要应对的是数据库读并发,没有解决数据库存储问题。试想一下:如果MySQL一张表的数据量过大怎么办?换言之,我们该如何解决MySQL的存储压力呢?答案之一就是分库分表。什么是分库?分库就是将数据库中的数据分散到不同的数据库上,可以垂直分库,也可以水平分库。......
  • 分表
    分表设计是数据库优化的一种常见手段,旨在通过将数据分散到多个表中来提高数据库的性能和扩展性。以下是分表设计的一些关键点:1.分表的原因性能提升:单表数据量过大时,查询、更新等操作的性能会下降。分表可以减少单次操作的数据量,提高响应速度。避免热点:将热点数据分散到不同的......
  • 【SQL】常用的分库策略有哪些
    分库是数据库设计中的一种常见策略,用于解决大规模数据处理和高并发访问的问题。通过将数据分布到多个数据库实例上,可以提高系统的可扩展性、性能和可用性。常用的分库策略主要包括垂直分库、水平分库和混合分库。以下是这些策略的详细介绍:1.垂直分库(VerticalSharding)垂......
  • 【SQL】分库分表带来的问题以及解决方案
    分库分表是解决大规模数据和高并发访问的有效方法,但它也会带来一些问题和挑战。以下是分库分表可能带来的主要问题:1.跨分片查询复杂性在分库分表的架构中,数据分布在多个数据库实例或表中,这导致跨分片的查询变得复杂。问题:需要跨多个数据库实例或表进行数据聚合。查询性......
  • thinkphp5.1水平分表实践(一)
    在thinkphp5.1中可以使用partition方法进行水平分表功能,但其分表功能较简单,不适用某些特殊场景。其在TP中的实现逻辑如下:文件路径:thinkphp\library\think\db\Query.php  (555行)/***得到分表的的数据表名*@accesspublic*@paramarray$data操作的数......
  • 深度解析:分库分表策略在数据库性能优化中的核心作用
        目录分库分表的核心原理分库(Sharding)分表(Partitioning)综合运用与挑战在探讨分库分表的深度理解之前,先回顾一下为什么数据库系统会面临性能瓶颈。随着互联网业务的飞速发展,数据量呈指数级增长,同时高并发的访问需求对数据库的读写性能提出了更高要求。传统的......