博主精品——Sharding-JDBC分库分表实战(4库32表)!

DBC 136 0

一、先看下简单的库、表结构

ORM框架自动生成的代码,太简单就不上代码了,主要是理解思路

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图
博主精品——Sharding-JDBC分库分表实战(4库32表)!插图2

二、引入依赖

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>
完整配置文件内容
需要注意的点
  • 如果你不想数据库和表的后缀是0
    • 那么需要在取模的时候+1即可,如:{id % 4 + 1}
  • 分片键不可以为String
    • 如果你的分片键类型是String那么会报错
  • 分库、分表键不能设置一样的(博主仅仅为了省事,理解思路即可[aru_51])
    • 如果设置一样的话,那么像博主这个分片规则结果如下(循环生成10条数据):
      • 博主精品——Sharding-JDBC分库分表实战(4库32表)!插图4

      • 博主精品——Sharding-JDBC分库分表实战(4库32表)!插图6

      • 博主精品——Sharding-JDBC分库分表实战(4库32表)!插图8

      • 博主精品——Sharding-JDBC分库分表实战(4库32表)!插图10

    • 所有数据打在了(1库1表)(2库2表)(3库3表)(4库4表)

引出两个问题

一)最新版本4.1.1与你的Spring版本兼容性有问题,使用下面这个版本即可

		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
			<version>4.0.0-RC1</version>
		</dependency>

二)dataSource这个bean无法注册

根据提示可知,实体类无法绑定多个数据源,我们加入下面代码解决
spring.main.allow-bean-definition-overriding=true

三、简单配置结束,上代码测试

package com.example.test05.demo.controller;


import com.example.test05.demo.mapper.TbUserMapper;
import com.example.test05.demo.model.TbUserDO;

import com.example.test05.demo.service.TbUserService;

import com.example.test05.demo.tool.JsonData;
import jdk.nashorn.internal.objects.annotations.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author DBC
 * @since 2021-11-05
 */

@RestController
@RequestMapping("/tbUserDO")
public class TbUserController {
    @Autowired
    private TbUserService tbUserService;

    @Autowired
    private TbUserMapper tbUserMapper;

    @PostMapping()
    public JsonData install() {
        for (int i = 0; i < 10; i++) {
            TbUserDO tbUserDO = new TbUserDO();
            tbUserDO.setId((long) i);
            tbUserDO.setName("大猪头" + i);
            tbUserDO.setAge("" + i);
            tbUserMapper.insert(tbUserDO);
        }
        return JsonData.buildSuccess();
    }

    @GetMapping()
    public JsonData chaxun() {
        List<TbUserDO> tbUserDOList = tbUserService.list();
        System.out.println(tbUserDOList.size());
        return JsonData.buildSuccess(tbUserDOList);
    }

    @DeleteMapping()
    public JsonData shanchu() {
        tbUserService.removeById(1);
        return JsonData.buildSuccess();
    }

    @PutMapping()
    public JsonData xiugai() {
        TbUserDO tbUserDO = new TbUserDO();
        tbUserDO.setId((long) 2);
        tbUserDO.setName("大猪头666");
        tbUserDO.setAge("");
        tbUserMapper.updateById(tbUserDO);
        return JsonData.buildSuccess();
    }




}

解析

我们从上面的代码也可以看出来,在我们配置好了之后,我们的代码是没有变化的,由Sharding-JDBC自动的帮我们处理拼接了sql
这是最简单的一种用法,简单的增删改查已经足够实现,具体自己测试即可,下面的将是进阶操作!

进阶操作——广播表

公共表属于系统中数据量较小,变动少,而且属于高频联合查询的依赖表。参数表、数据字典表等属于此类型。可以将这类表在每个数据库都保存一份,所有更新操作都同时发送到所有分库执行。接下来看一下如何使用Sharding-JDBC实现公共表

建对应的表、简单的ORM操作

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图12

在配置文件追加广播表

#配置广播表
spring.shardingsphere.sharding.broadcast-tables=tb_type

测试一下

    @PostMapping("installType")
    public JsonData installType() {

        TbType tbType = new TbType();
        tbType.setType("大猪头");
        tbTypeMapper.insert(tbType);

        return JsonData.buildSuccess();
    }
解析

大功告成,没有什么特别的操作,这样之后,所有的表都会插入同样的数据了,这里就不上图了,省点资源吧[aru_15]

进阶操作——绑定表

  • 什么是绑定表
    • 指分片规则一致的主表和子表
    • 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升

先看数据库

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图14
博主精品——Sharding-JDBC分库分表实战(4库32表)!插图16

我们每个库有主表tb_user4张表,和子表tb_user_item四张表。
分片规则和之前的发生了一些改变,分库我们主表、子表都还是用的id来作为分片键,而分表我们换成了dev_id来作为分片键

画一张图辅助理解

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图18

解析

如上图所示,如果我们的主表与子表的分片规则相同,那么我们在发起sql的时候,我们可以直接配置主表匹配对应的子表。如果我们还如下图这样发起请求,就会造成不必要的性能消耗,笛卡尔积爆炸!

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图20

可以看到,博主举例的红框框是我们需要的,其他很多的都是不需要的sql,并无意义,但是却发起了请求,这是极其糟糕的!

配置对应的分表策略

#配置分库规则
spring.shardingsphere.sharding.tables.tb_user.database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.tb_user.database-strategy.inline.algorithm-expression=ds$->{id % 4 + 1}
spring.shardingsphere.sharding.tables.tb_user_item.database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.tb_user_item.database-strategy.inline.algorithm-expression=ds$->{id % 4 + 1}

# 指定st_user表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},
# 但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
# 指定st_user表的分片策略,分片策略包括【分片键和分片算法】`
spring.shardingsphere.sharding.tables.tb_user.actual-data-nodes=ds$->{1..4}.tb_user$->{1..4}
spring.shardingsphere.sharding.tables.tb_user.table-strategy.inline.sharding-column=dev_id
spring.shardingsphere.sharding.tables.tb_user.table-strategy.inline.algorithm-expression=tb_user$->{dev_id % 4 + 1}

# 指定st_user_item表的分片策略,分片策略包括【分片键和分片算法】`
spring.shardingsphere.sharding.tables.tb_user_item.actual-data-nodes=ds$->{1..4}.tb_user_item$->{1..4}
spring.shardingsphere.sharding.tables.tb_user_item.table-strategy.inline.sharding-column=dev_id
spring.shardingsphere.sharding.tables.tb_user_item.table-strategy.inline.algorithm-expression=tb_user_item$->{dev_id % 4 + 1}

#配置广播表
spring.shardingsphere.sharding.broadcast-tables=tb_type

#配置绑定表
spring.shardingsphere.sharding.binding-tables[0] = tb_user,tb_user_item
配置直接放全,相信很容易看出来,我们配置绑定表的话,就是最后一行代码即可
spring.shardingsphere.sharding.binding-tables[0] = tb_user,tb_user_item

我们来看看效果

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图22

绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升

进阶操作——多种分片策略实战

为了能够有更加自定义的分库分表操作,我们需要在java配置一些我们需要的分库分表策略

温馨提示

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图24
之前我们的分库分表规则全部注释,换成下面的配置

#精准分片-水平分表
# 指定product_order表的数据分布情况,配置数据节点,在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.tb_user.actual-data-nodes=ds$->{1..4}.tb_user$->{1..4}

#指定精准分片算法(水平分库) 根据id分库
spring.shardingsphere.sharding.tables.tb_user.database-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.tb_user.database-strategy.standard.precise-algorithm-class-name=com.example.test05.demo.config.CustomDBPreciseShardingAlgorithm
#指定精准分片算法(水平分表)
spring.shardingsphere.sharding.tables.tb_user.table-strategy.standard.sharding-column=dev_id
spring.shardingsphere.sharding.tables.tb_user.table-strategy.standard.precise-algorithm-class-name=com.example.test05.demo.config.CustomTablePreciseShardingAlgorithm

#范围分片(水平分表)
spring.shardingsphere.sharding.tables.tb_user.table-strategy.standard.range-algorithm-class-name=com.example.test05.demo.config.CustomRangeShardingAlgorithm

分库配置

CustomDBPreciseShardingAlgorithm

点击查看完整内容

CustomTablePreciseShardingAlgorithm

点击查看完整内容
解析

博主精品——Sharding-JDBC分库分表实战(4库32表)!插图26
其实箭头所指的就是和我们前面的简单配置相同,也就是这个ds$->{id % 4 + 1}
分库和分表同理可得

注意:这里我们已经完成了基本的配置,简单的增删改查已经可以实现了,但是如果调用between有些版本会报错,就算不报错,也会发生恐怖的笛卡尔积!我们需要配置一下

CustomRangeShardingAlgorithm

点击查看完整内容
温馨提示

这里要需要注意的是,我们的表是从1开始的,所以这里要加一,要不然我们的4号库不会被调用到。切记!
博主精品——Sharding-JDBC分库分表实战(4库32表)!插图28

大功告成!撒花[aru_50]

总结

到了这里,我们已经基本完成了分库分表的基础操作!后面的操作留给高端的架构师吧[aru_55]

发表评论 取消回复
表情 图片 链接 代码

分享