ShardingSphere实战(2)- 水平分表

上篇博客,我们讲了 ShardingSphere实战(1)- 分库分表基础知识,这篇博客,正式开始实操。

项目环境:
JDK11
MySQL 8.0.30
Springboot 2.7.4 + Mybatis + ShardingSphere + HikariCP 连接池

一、Maven 依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.4</version>
</parent>
    
<dependencies>
     <dependency>
         <groupId>com.google.guava</groupId>
         <artifactId>guava</artifactId>
         <version>33.2.1-jre</version>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>

     <!-- mysql驱动 -->
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
     </dependency>
     <!-- ShardingSphere -->
     <dependency>
         <groupId>org.apache.shardingsphere</groupId>
         <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
         <version>4.1.1</version>
     </dependency>
     <!--HikariCP 高性能的JDBC连接池-->
     <dependency>
         <groupId>com.zaxxer</groupId>
         <artifactId>HikariCP</artifactId>
         <version>5.0.0</version>
     </dependency>
     <!--mybatis-->
     <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.2.0</version>
     </dependency>
 </dependencies>

二、创建数据库

在这里插入图片描述

create database ds-0;

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_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
)

三、项目搭建

在这里插入图片描述

package com.shardingsphere.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
@MapperScan({"com.shardingsphere.demo.dal.mapper"})
public class ShardingsphereDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShardingsphereDemoApplication.class, args);
    }

    @RequestMapping
    public String health() {
        return "shardingsphere-demo is ok!";
    }
}

实体类以及 mapper 的具体代码就不贴了,就是一个简单的 springboot + mybatis 项目。

四、单个表配置 ShardingSphere 分片策略

# sharding-jdbc 水平分表策略
# 给数据源起别名,这里名称需要和下面的一致
spring.shardingsphere.datasource.names=ds-0

# 配置数据源
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:3306/ds-0?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.ds-0.username=xxx
spring.shardingsphere.datasource.ds-0.password=xxx

####################### 配置分片表t_order #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds-0.t_order_$->{0..1}

### 分表策略
# 分表分片健
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 % 2}

# 是否开启 SQL解析日志
spring.shardingsphere.props.sql.show=true

mybatis.mapper-locations=classpath:sqlmapper/*.xml

1. 插入数据

/**
 * 单个表水平分表测试-保存
 */
@GetMapping("/test1")
public String test1(@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);
    }
    return "success";
}

运行代码,可以看到 order_id 为偶数进了 t_order_0,为奇数进了t_order_1,和我们配置的分片规则一致。

在这里插入图片描述

2. 查询数据

/**
 * 单个表水平分表测试-查询
 */
@GetMapping("/test2")
public String test2(@RequestParam("orderId") Long orderId) {

    OrderDO orderDO = orderMapper.selectByPrimaryKey(orderId);
    log.info("orderDO: {}", orderDO.toString());

    return "success";
}

运行代码,可以看到 order_id 为偶数查询 t_order_0,为奇数查询t_order_1,和我们配置的分片规则一致。
在这里插入图片描述
到目前为止,一个最简单的分表 demo 就完成了。

五、多个表配置 ShardingSphere 分片策略

如果我们还有一张t_order_item表,也需要分表,并且同样需要按照order_id分片
在上面配置的基础上,加上下面的配置:

####################### 配置分片表t_order_item #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds-0.t_order_item_$->{0..1}

### 分表策略
# 分表分片健
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 % 2}

1. 插入数据

/**
 * 多个表水平分表测试-保存
 */
@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";
}

运行结果就不看了,和上面一致,按照order_id分片

2. 查询数据

/**
 * 多个表水平分表测试-查询
 */
@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>

和单表不一样,这次是t_ordert_order_item表关联查询,观察结果:
在这里插入图片描述
可以看到,sql 执行了两次,也就是说取的是笛卡尔积,可以想象,如果我们分表数量多,查询效率肯定极低,所以针对这种情况,我们需要配置绑定表

六、完整配置

为了方便查看,下面放一个本篇博客关于ShardingSphere的完整配置:

# sharding-jdbc 水平分表策略
# 给数据源起别名,这里名称需要和下面的一致
spring.shardingsphere.datasource.names=ds-0

# 配置数据源
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

####################### 配置分片表t_order #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds-0.t_order_$->{0..1}

### 分表策略
# 分表分片健
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 % 2}


####################### 配置分片表t_order_item #######################
# 指定真实数据节点
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds-0.t_order_item_$->{0..1}

### 分表策略
# 分表分片健
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 % 2}

# 是否开启 SQL解析日志
spring.shardingsphere.props.sql.show=true

mybatis.mapper-locations=classpath:sqlmapper/*.xml

总结:本篇博客实现了水平分表,后续会陆续更新分库分表绑定表广播表

下一篇:ShardingSphere实战(3)- 快速实现分库分表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值