sharding-jdbc分库分表

目录

分库分表

分库分表概述

分库分表的方式

一.垂直分表

1.定义

2.优势

3.垂直分表的原则

二.垂直分库

1.垂直分表存在的问题

2.垂直分库的定义

3.垂直分库的优势

4.垂直分库的缺点

三.水平分表

1.定义

2.优势

3.缺点

四.水平分库

1.定义

2.优势

分库分表总结

sharding-jdbc

一.sharding-jdbc简介

二.sharding-jdbc的重要名词介绍

三.sharding-jdbc执行原理

举例

1.首先开发者编写sql语句

2.sql解析

3.执行器优化

4.sql路由

5.改写sql

[6. sql执行](#6. sql执行)

7.结果归并

四.sharding-jdbc分片方式介绍

sharding-jdbc配置步骤

基于inline实现水平分表

1.准备数据库

2.导入sharding-jdbc依赖

3.在application文件中书写配置

4.插入测试

[​编辑 基于inline实现水平分库分表](#编辑 基于inline实现水平分库分表)

1.准备数据库

2.application配置

测试

实现sharding-jdbc广播表

1.准备数据库

2.application配置

3.测试

基于inline实现垂直分库

1.准备数据库

2.application配置

3.测试

配置默认的数据源(数据库)

1.创建一个默认库

2.application配置

3.测试

inline模式小结:


分库分表

分库分表概述

分库分表本质上就是解决由于库表数据量过大导致数据库性能下降的问题;

核心操作:

  • 将原来独立的数据库拆分成若干个数据库
  • 将原来的大表(存储千万条数据的表)拆分成若干个小表

分库分表解决了数据量过大导致数据库性能下降的问题

分库分表的方式

分库分表包括分库和分表,包括垂直分库,垂直分表,水平分库,水平分表

一.垂直分表

1.定义
  • 垂直分表就是在同一数据库内将一张表按照指定字段分成若干表(即几个字段为一张表),这样一来每张表仅存储其中一部分的字段
  • 垂直分表拆解了原来表的结构,拆分的表之间是一对一的关系
2.优势

由于有些表中的字段有些需要频繁查询,有些不太需要,所以需要把数据表进行分表,把冷热数据字段分离所以优势为:充分提高了热点数据的操作效率,避免了io争抢过度并减少锁表的几率

3.垂直分表的原则
  • 不常用的字段单独放在一张表(因为数据库加载数据时,会将表整行的信息加载)
  • 把text(大文本存储),blob(图片,视频类存储)等大字段拆分出来放在附表中
  • 经常组合查询的字段放在同一张表中,避免多表查询,性能最高

二.垂直分库

1.垂直分表存在的问题
  • 经过垂直分表后表的查询性能确实提高了,但是数据始终限制在同一台机器中,因此每个表还是竞争同一个物理机的cpu,内存,网络io,磁盘
  • 单台服务器的性能瓶颈,通过垂直分表始终得不到突破
2.垂直分库的定义

垂直分库是按照业务将表进行归类,然后把不同类的表分布到不同的数据库上面而每个库又可以放到不同的服务器上,核心概念就是-->专库专用

3.垂直分库的优势
  • 可以通过不同的表的业务聚合(聚合为库),使得数据库维护更加清晰
  • 能对不同业务的数据进行分级管理,维护,监控和扩展
  • 高并发场景下,垂直分库在一定程度上提高了磁盘io和数据库的连接数,并改善了单机硬件资源的瓶颈问题
4.垂直分库的缺点

垂直分库依然无法解决库中表单数据量过大的问题

三.水平分表

1.定义
  • 水平分表就是在同一个数据库内,把同一个表的数据按照一定规则拆到多个表中,表的结构没有变化。
  • 水平分表可以解决单表中数据量大的问题
2.优势
  • 优化单一表数据量过大而产生的性能问题,让一张表的数据量减少
  • 避免io争抢并减少锁表的几率
3.缺点

水平分表仅仅解决了单表数据量过大的问题,但是没有解决单库数据类过大的问题

四.水平分库

1.定义
  • 水平分库可以看做水平分表的进一步拆分,就是把同一张表的数据按照一定的规则拆分到不同的数据库中每个库又可以部署到不同的服务器中
  • 水平分库解决了单库数据量过大的问题,突破了服务器物理存储的瓶颈
  • 水平分库就是水平分表的plus版,把分出的表分到不同的库中
2.优势

解决了单库中数据量过大的问题

分库分表总结

分库分表方式:垂直分表、垂直分库、水平分库和水平分表

**垂直分表:**可以把一个宽表的字段按访问频次、是否是大字段的原则拆分为多个表,这样既能使业务清晰,还能提升部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失【同一库中将单张表按照字段拆分成若干表,拆分后表的记录行数不变】。

**垂直分库:**可以把多个表按业务耦合松紧归类,分别存放在不同的库,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能,同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案。但是它需要解决跨库带来的所有复杂问题。 【根据业务将表分组形成不同的库,这些库又可以部署到不同的数据库中-专库专用

**水平分表:**可以把一个表的数据(按数据行)分到多个同一个数据库的多张表中,每个表只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。【同一数据库中将大表拆分成若干小表,每张表的结构一致,但保存的数据不同

水平分库:可以把表的数据(按数据行)分 到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,大大提升性能。它不仅需要解决跨库带来的所有复杂问题,还要解决数据路由的问题(数据路由问题后边介绍)。

最佳实践:

一般来说,在系统设计阶段 就应该根据业务耦合松紧来确定垂直分库,垂直分表 方案。当然在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术 等方案。若数据量极大,且持续增长,再考虑水平分库水平分表方案。

总之,基于开发和维护成本比考虑,非必须,不要对数据库做分库分表处理!

sharding-jdbc

一.sharding-jdbc简介

​ Sharding-jdbc是ShardingSphere的其中一个模块,定位为==轻量级Java框架==,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架

  • 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
  • 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。

Sharding-JDBC的核心功能为数据分片读写分离 ,通过Sharding-JDBC,应用可以透明的使用jdbc访问已经分库分表、读写分离的多个数据源,而不用关心数据源的数量以及数据如何分布。

二.sharding-jdbc的重要名词介绍

  • 逻辑表(LogicTable):进行水平拆分的时候同一类型(逻辑、数据结构相同)的表的总称。例:用户数据根据主键尾数拆分为2张表,分别是tab_user_0到tab_user_1,他们的逻辑表名为tab_user。逻辑表是面向开发的,实际上并不存在。

  • 真实表(ActualTable):在分片的数据库中真实存在的物理表。即上个示例中的tab_user_0到tab_user_1。

  • 数据节点(DataNode):数据分片的最小单元。由数据源名称和数据表组成,例:spring-boot_0.tab_user_0,spring-boot_0.tab_user_1,spring-boot_1.tab_user_0,spring-boot_1.tab_user_1。数据节点就是数据库名.物理表(真实表)的名字

    说白了,具体到指定库下的指定表就是一个数据节点;

  • 动态表(DynamicTable):逻辑表和物理表不一定需要在配置规则中静态配置。如,按照日期分片的场景,物理表的名称随着时间的推移会产生变化(股票流水)。就是动态产生的真实表,比如根据当前日期给真实表来命名

  • 广播表(公共表):指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致 。适用于数据量不大且需要与海量数据的表进行关联查询 的场景,例如:字典表。公共表就是在每个库中都有的一张表(字段名,数据量)完全相同

  • 绑定表(BindingTable):指E。例如:t_order表和t_order_item表,均按照order_no分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。绑定表的目的就是防止进行多表关联查询时,两张表不在同一个数据库中,导致查询效率下降的问题。

  • 分片键(ShardingColumn):分片字段用于将数据库(表)水平拆分的字段,支持单字段及多字段分片。例如上例中的order_id。

    一般在业务中经常查询使用的**字段(如主键id)**会作为分片键;就是用来分片的字段就是分片键

三.sharding-jdbc执行原理

执行原理为:核心由SQL解析 => 执行器优化 => SQL路由 => SQL改写 => SQL执行 => 结果归并的流程组成

举例

现在有一张逻辑表,四张真实表,这四张表进行了分库分表操作,2个库ds0,ds1,采用的分片键为id,逻辑表为t_user,真实表为t_user_0、t_user_1两张表,分库、分表算法为均为取余(%2)。

逻辑表:t_user

物理表:ds0.t_user_1,ds0.t_user_2,ds1.t_user_1,ds1.t_user_2

1.首先开发者编写sql语句
sql 复制代码
select * from t_user where id=10

t_user这张表是逻辑表,是不存在的

2.sql解析

获取逻辑表名称来匹配真实表,获取分片键,片键查询条件(=,in,>,<,between and),条件值(10)

3.执行器优化

目的:将符合sharding规范的sql改为符合规范

如把 select * from t_user where id =10 or id=20 or id=30

改为 select * from t_user where id in (10,20,30)

4.sql路由

路由的本质就是根据逻辑sql找到当前sql应该去执行哪张库下的哪张表(根据查询条件的不同肯有多张真实表)

如根据id=10来知道 id%2-->0,就是去操作0号数据库的0号数据表

5.改写sql

sharding-jdbc将逻辑表改为通过路由找到的真实表**(匹配到几张真实表就有几条sql语句)**

select * from ds0.t_user_0 where id=10

6. sql执行

sharding-jdbc将改写的sql语句(可能有多张表)多线程并发发送sql语句给对应的数据节点(数据源.物理表名称)

7.结果归并

sharding-jdbc将多个数据节点执行sql形成的多个结果集 进行合并,然后以jdbc的方式响应给orm框架

四.sharding-jdbc分片方式介绍

sharding-jdbc实现数据分片有4种策略:

  • inline模式

    • 使用最简单,开发成本比较低;
    • 只能使用单个字段作为分片键;
    • 基于行表达式定义分片规则;
    复制代码
    根据groovy表达式来表示分库分表的策略:ds0.t_user_1,ds0.t_user_2,ds1.t_user_1,ds1.t_user_2

    表达式: ds(0..1).t_user_{0..1}

    t_user_${userId%2}

  • standard标准分片模式

    • 用户可通过代码自定义复杂的分片策略;
    • 同样只能使用单个字段作为分片键;
  • complex复合分片模式

    • 用于多分片键的复合分片策略(多片键)
  • Hint强制分片模式

    • 不指定片键,通过代码动态指定路由规则
    • 强制分片策略(强制路由)

sharding-jdbc配置步骤

数据源-->数据源连接数据库-->逻辑表对应的数据节点(数据源.物理表)-->分库分表策略

基于inline实现水平分表

1.准备数据库

sql 复制代码
#创建数据库
CREATE DATABASE `order_db_1` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
#建表
USE order_db_1;
DROP TABLE IF EXISTS `t_order_1`;
CREATE TABLE `t_order_1` (
    `order_id` BIGINT (20) NOT NULL COMMENT '订单id',
    `price` DECIMAL (10, 2) NOT NULL COMMENT '订单价格',
    `user_id` BIGINT (20) NOT NULL COMMENT '下单用户id',
    `status` VARCHAR (50) CHARACTER
SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
 PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = INNODB CHARACTER
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS `t_order_2`;
CREATE TABLE `t_order_2` (
    `order_id` BIGINT (20) NOT NULL COMMENT '订单id',
    `price` DECIMAL (10, 2) NOT NULL COMMENT '订单价格',
    `user_id` BIGINT (20) NOT NULL COMMENT '下单用户id',
    `status` VARCHAR (50) CHARACTER
SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
 PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = INNODB CHARACTER
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2.导入sharding-jdbc依赖

html 复制代码
 <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!--引入sharding依赖-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>
    </dependencies>

3.在application文件中书写配置

mybatis配置:

html 复制代码
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.itheima.sharding.entity
spring.profiles.active=test1

sharding-jdbc配置

Haskell 复制代码
# 分表配置
# 数据源名称,多数据源以逗号分隔,一个数据库对应一个数据源
spring.shardingsphere.datasource.names=ds1
#让数据源连接指定的数据库
# 数据库连接池类名称
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://192.168.200.130:3306/order_db_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.ds1.username=root
# 数据库密码
spring.shardingsphere.datasource.ds1.password=1234

#配置当前逻辑表对应的数据节点
# 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds1.t_order_${1..2}

# 指定表的分片策略(根据此分片条件来找到逻辑表对应哪个真实表) order_id%2+1
# 分片列(键)名称
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分片算法行表达式,需符合 groovy 语法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_${order_id % 2 +1}

#开启sql显示到终端
spring.shardingsphere.props.sql.show=true

注意:在sql-xml文件中书写的逻辑表为t_order

html 复制代码
    <select id="selectByRange2" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from t_order
        where  order_id between #{start} and #{end} and user_id=#{userId}
    </select>

4.插入测试

java 复制代码
@SpringBootTest
public class TestAll {

    @Autowired
    private TOrderMapper tOrderMapper;
    @Test
   public void test1() {
        int orderId=0;
        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            //保证随机生成奇数或者偶数
            orderId+=random.nextInt(2)+1;
            TOrder order = TOrder.builder().orderId(Long.valueOf(orderId))
                    .userId(Long.valueOf(i))
                    .status("1")
                    .price(new BigDecimal(300))
                    .build();
            tOrderMapper.insert(order);
        }
    }
}

t_order_1:

t_order_2:

基于inline实现水平分库分表

1.准备数据库

truncate table t_order_1-->把表的原来数据给删除

2.application配置

Haskell 复制代码
# 分表配置
# 数据源名称,多数据源以逗号分隔,一个数据库对应一个数据源
spring.shardingsphere.datasource.names=ds1,ds2
#让数据源连接指定的数据库
# 数据库连接池类名称
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://192.168.200.130:3306/order_db_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.ds1.username=root
# 数据库密码
spring.shardingsphere.datasource.ds1.password=1234

#配置第二个数据源连接的数据库
# 数据库连接池类名称
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://192.168.200.130:3306/order_db_2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.ds2.username=root
# 数据库密码
spring.shardingsphere.datasource.ds2.password=1234

#配置当前逻辑表对应的数据节点
# 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds${1..2}.t_order_${1..2}

#指定库的分片策略 (根据此分片条件来找到要操作哪个数据库) user_id%2+1
# 分片列(键)名称
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
# 分片算法行表达式,需符合 groovy 语法
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds${user_id % 2 +1}


# 指定表的分片策略(根据此分片条件来找到逻辑表对应哪个真实表) order_id%2+1
# 分片列(键)名称
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分片算法行表达式,需符合 groovy 语法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_${order_id % 2 +1}

#开启sql显示到终端
spring.shardingsphere.props.sql.show=true

测试

java 复制代码
@Test
    public void test2(){
        int orderId=0;
        int userId=0;
        Random random = new Random();
        for (int i = 0; i < 40; i++) {
            //保证随机生成奇数或者偶数
            orderId+=random.nextInt(2)+1;
            userId+=random.nextInt(2)+1;
            TOrder order = TOrder.builder().orderId(Long.valueOf(orderId))
                    .userId(Long.valueOf(userId))
                    .status("1")
                    .price(new BigDecimal(300))
                    .build();
            tOrderMapper.insert(order);
        }
    }

实现sharding-jdbc广播表

  • 广播表属于数据库中数据量较小和变动较少,且存在高频联合查询的表,比如:数据字典表等属于此广播表。
  • 可以将这类表在每个数据库都保存一份,所有操作都同时发送到所有分库执行。

1.准备数据库

2.application配置

这里每个数据库中都有这张表,我们在之前已经配置了数据源并让数据源连接了对应的数据库,因为这个表是公共表,所以不需要配置公共表这个逻辑表对应的数据节点(但是要保证逻辑表的名字与这个公共表的名字一样)

java 复制代码
# 指定t_dict为公共表,多个公共表以逗号间隔
spring.shardingsphere.sharding.broadcast‐tables=t_dict

3.测试

java 复制代码
 @Autowired
    private TDictMapper tDictMapper;

    /**
     * 测试广播表:
     *      当对法广播表进行增删改操作时,操作的sql会广播给各个数据源
     */
    @Test
    public void commonTable(){
        TDict build = TDict.builder().dictId(1l).code("666").type("1").value("888")
                .build();
        tDictMapper.insert(build);
    }

基于inline实现垂直分库

1.准备数据库

sql 复制代码
#创建数据库
CREATE DATABASE `user_db` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
#建表
USE user_db;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
 `user_id` BIGINT (20) NOT NULL COMMENT '用户id',
 `fullname` VARCHAR (255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户姓名',
 `user_type` CHAR (1) DEFAULT NULL COMMENT '用户类型',
 PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = INNODB CHARACTER
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2.application配置

基本步骤:配置数据源,让这个数据源连接user_db数据库,然后配置逻辑表对应的数据节点,

这里由于t_user逻辑表对应的是单库单表,因此不需要配置分库分表策略

Haskell 复制代码
# 分表配置
# 数据源名称,多数据源以逗号分隔,一个数据库对应一个数据源
spring.shardingsphere.datasource.names=ds1,ds2,udb
#让数据源连接指定的数据库
# 数据库连接池类名称
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://192.168.200.130:3306/order_db_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.ds1.username=root
# 数据库密码
spring.shardingsphere.datasource.ds1.password=1234

#配置第二个数据源连接的数据库
# 数据库连接池类名称
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://192.168.200.130:3306/order_db_2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.ds2.username=root
# 数据库密码
spring.shardingsphere.datasource.ds2.password=1234

#配置ubd数据源连接的数据用户库
# 数据库连接池类名称
spring.shardingsphere.datasource.udb.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.udb.driver-class-name=com.mysql.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.udb.url=jdbc:mysql://192.168.200.130:3306/user_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.udb.username=root
# 数据库密码
spring.shardingsphere.datasource.udb.password=1234


#配置当前逻辑表对应的数据节点
# 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持 inline 表达式
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds${1..2}.t_order_${1..2}
# 由于这个t_user逻辑表只对应了单库单表,所以不需要写分库分表策略
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=udb.t_user


#指定库的分片策略 (根据此分片条件来找到要操作哪个数据库) user_id%2+1
# 分片列(键)名称
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
# 分片算法行表达式,需符合 groovy 语法
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds${user_id % 2 +1}


# 指定表的分片策略(根据此分片条件来找到逻辑表对应哪个真实表) order_id%2+1
# 分片列(键)名称
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
# 分片算法行表达式,需符合 groovy 语法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_${order_id % 2 +1}

# 指定t_dict为公共表,多个公共表以逗号间隔
# 这里的user_db库没有t_dict这个公共表,会报错
#spring.shardingsphere.sharding.broadcast‐tables=t_dict

#开启sql显示到终端
spring.shardingsphere.props.sql.show=true

3.测试

java 复制代码
    @Autowired
    private TUserMapper tUserMapper;

    @Test
    public void test04(){
        TUser user = TUser.builder().userId(133l).userType("1")
                .fullname("laozhang").build();
        tUserMapper.insert(user);
    }

配置默认的数据源(数据库)

默认库的作用就是,如果一个逻辑表没有给他配置对应的数据节点,那么对这个逻辑表进行操作时,就会去默认库查看是否有这张逻辑表,如果有就进行sql语句,没有就报错

如果没有配置分片策略,则可指定默认访问的数据源,也就是说只需指定数据源,无需指定数据节点、库和表的分片策略也无需执行;

如果在进行相关操作时,发现逻辑表没有对应的数据节点、库表的分片配置,则走默认指定的数据源;

1.创建一个默认库

sql 复制代码
-- 构建数据
create database default_db character set utf8;
use default_db;
-- 构建表
create table tb_log (
    id bigint primary key ,
    info varchar(30)
);

2.application配置

默认库的作用就是,如果一个逻辑表没有给他配置对应的数据节点,那么对这个逻辑表进行操作时,就会去默认库查看是否有这张逻辑表,如果有就进行sql语句,没有就报错

Haskell 复制代码
# 配置shardingjdbc数据源
# 数据源名称,多数据源以逗号分隔
spring.shardingsphere.datasource.names=defdb
# 配置数据源参数
# 数据库连接池类名称
spring.shardingsphere.datasource.defdb.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动类名
spring.shardingsphere.datasource.defdb.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库 url 连接
spring.shardingsphere.datasource.defdb.url=jdbc:mysql://192.168.200.130:3306/default_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai
# 数据库用户名
spring.shardingsphere.datasource.defdb.username=root
# 数据库密码
spring.shardingsphere.datasource.defdb.password=root

# 配置默认数据源(特点:对于不做分片处理的操作,都会直接访问默认数据源
# 未配置分片规则的表将通过默认数据源定位
spring.shardingsphere.sharding.default-data-source-name=defdb

3.测试

java 复制代码
    /**
     * 测试默认数据源
     *  对于没有做分片处理的操作,则会直接访问默认数据源处理
     */
    @Test
    public void test5(){
        TbLog log = TbLog.builder().id(2l).info("这是一个测试2").build();
        tbLogMapper.insert(log);
    }

inline模式小结:

  • 优点:
    • 配置简单,开发成本低;
    • 便于理解和维护;
  • 缺点:
    • 复杂的分片策略支持不友好;
    • 对范围查询支持不太友好,动辄全节点查询,查询效率低下;
相关推荐
FuLLovers26 分钟前
2024-09-13 冯诺依曼体系结构 OS管理 进程
linux·开发语言
深海呐1 小时前
Android AlertDialog圆角背景不生效的问题
android
IT毕设梦工厂1 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
ljl_jiaLiang1 小时前
android10 系统定制:增加应用使用数据埋点,应用使用时长统计
android·系统定制
花花鱼1 小时前
android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。
android
everyStudy1 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
小诸葛的博客1 小时前
pg入门1——使用容器启动一个pg
数据库
luthane1 小时前
python 实现average mean平均数算法
开发语言·python·算法
Ylucius2 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习