微服务之ShardingSphere

文章目录

问题分析

数据库中的数据量猛增,访问性能也变慢了,优化迫在眉睫 ?

  1. 关系型数据库本身比较容易成为系统瓶颈:单机存储容量、数据库连接数、处理能力都有限。
  2. 当单表的数据量达到1000W或100G以后,由于查询维度较多,即使做了优化索引等操作, 查询性能仍下降严重。

方案1:

通过提升服务器硬件能力来提高数据处理能力,比如增加存储容量 、CPU等,这种方案成本很高,并且如果瓶颈在MySQL本身那么提高硬件也是有很的。

方案2:

把数据分散在不同的数据库中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的;

分库分表概述

分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题;

1.将原来独立的数据库拆分成若干数据库组成;

2.将原来的大表(存储近千万数据的表)拆分成若干个小表;

目的:使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

数据库拆分策略




  1. 垂直分割
    垂直分割是将一个表按照列的方式拆分成多个表,减少单个表的记录数和列数,提高查询性能。垂直分割一般
    分为两种: 基于功能分割和基于范式分割。
    例如,将一个用户表拆分为登录信息表、用户信息表和账户信息表。
  2. 水平分割
    水平分割是将一个表按照行的方式拆分成多个表,将数据存储到多个服务器上,提高查询性能。水平分割一般按照主键或按照特定的列进行分割。
    例如,将一个订单表按照订单号拆分成多个表。
  3. 读写分离
    读写分离是将对数据库的读操作和写操作拆分到不同的服务器上,减轻单个数据库的负载压力,提高查询性能。
    例如,将一个电商网站的读取操作分配到从数据库上,将写操作分配到主数据库上。
  4. 分片
    分片是将一个大型数据表按照某个维度拆分成多个小的数据表,并将数据存储到多个服务器上。分片一般按照分片键进行分割,
    例如,将一个电商网站的订单表按照某个地理位置分割成多个子表。

ShardingSphere简介

Apache ShardingSphere是一款开源的分布式数据库中间件组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立的产品组成。

ShardingSphere定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据

库的 计算和存储能力,而并非实现一个全新的关系型数据库。

1) Sharding-JDBC:被定位为轻量级Java框架,在Java的JDBC层提供的额外服务,以jar包形式使用。直接使用代码实现数据库中间件(本篇博客学习这个)。

2) Sharding-Proxy:被定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版 本,用于完成对异构语言的支持。类似于MyCat,是个第三方插件,只用这个也可实现读写分离。

3) Sharding-Sidecar:被定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代理所有对数据库的访问。

ShardingSphere-JDBC

ShardingSphere-JDBC 是 ShardingSphere 的第一个产品,也是 ShardingSphere 的前身, 我们经常简称之为:sharding-jdbc 。 它定位为轻量级 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 的本质上就是实现 JDBC 的核心接口。

读写分离(水平拆分库)

我们使用ShardingSphere-JDBC+mybatisplus进行读写分离。

3380中smbms为主库,3380中smbms为从库

2个库中都需同时存在smbms_user表,要求结构相同

如果你还没有配置MySQL的读写分离可参考我的博客MySQL的读写分离配置

创建项目sharding-jdbc-01


整理代码

删除没有用的文件

新增文件User

com.hsh.shardingjdbc01文件夹下新建pojo文件夹

pojo文件夹下新建新建类User

java 复制代码
package com.hsh.shardingjdbc01.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("smbms_user")
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;// 主键ID
    private String userCode;// 用户编码
    private String userName;// 用户名称
    private String userPassword;// 用户密码
    private Integer gender;// 性别(1:女、 2:男)
    private Date birthday;//  出生日期
    private String phone;//  手机
    private String address;//  地址
    private Long userRole;// 用户角色(取自角色表-角色id)
    private Long createdBy;// 创建者(userId)
    private Date creationDate;// 创建时间
    private Long modifyBy; // 更新者(userId)
    private Date modifyDate; // 更新时间
}

新增文件Bill

com.hsh.shardingjdbc01.pojo文件夹下新建新建类Bill

java 复制代码
package com.hsh.shardingjdbc01.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("smbms_bill")
public class Bill {
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;   //id
    private String billCode; //账单编码
    private String productName; //商品名称
    private String productDesc; //商品描述
    private String productUnit; //商品单位
    private Integer productCount; //商品数量
    private BigDecimal totalPrice; //总金额
    private Integer isPayment; //是否支付
    private Integer providerId; //供应商ID
    private Integer createdBy; //创建者
    private String creationDate; //创建时间
    private Integer modifyBy; //更新者
    private Date modifyDate;//更新时间
}

新增UserMapper

com.hsh.shardingjdbc01文件夹下新建mapper文件夹

mapper文件夹下新建新建类UserMapper

java 复制代码
package com.hsh.shardingjdbc01.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hsh.shardingjdbc01.pojo.User;

public interface UserMapper extends BaseMapper<User> {
}

新增BillMapper

com.hsh.shardingjdbc01.mapper文件夹下新建新建类BillMapper

java 复制代码
package com.hsh.shardingjdbc01.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hsh.shardingjdbc01.pojo.Bill;

public interface BillMapper extends BaseMapper<Bill> {
}

启动类加入扫包

java 复制代码
package com.hsh.shardingjdbc01;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.hsh.shardingjdbc01.mapper")
public class ShardingJdbc01Application {
    public static void main(String[] args) {
        SpringApplication.run(ShardingJdbc01Application.class, args);
    }
}

引入依赖

xml 复制代码
<!-- sharding-jdbc -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.0</version>
</dependency>
<!--阿里数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

编写配置文件

application.yml

yml 复制代码
server:
  port: 8080
mybatis-plus:
  type-aliases-package: com.hz.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false
spring:
  profiles:
    active: 读写分离

application-读写分离.yml

注意我这里之所把这个拆分出来是为了下面的代码方便演示。

yml 复制代码
spring:
  shardingsphere:
    masterslave:
      load-balance-algorithm-type: round_robin #从库 负载均衡轮询  如果读是从两个从库读,为了分担压力所以要负载均衡轮询
      name: ds  # 数据源 可以随便起名字
      master-data-source-name: db1 #主库  可以随便起名字
      slave-data-source-names: db2 #从库,多个可以使用,隔开  可以随便起名字
    datasource:
      names: db1,db2
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3380/smbms
        username: root
        password: root
      db2:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3381/smbms
        username: root
        password: root
    props:
      sql:
        show: true #打印SQL语句
  main:
    allow-bean-definition-overriding: true # 允许覆盖bean  可以理解为禁用之前的配置的单数据的配置方法

编写测试方法

编写查看测试方法

java 复制代码
@Autowired
private UserMapper userMapper;
@Test
void find() {
    userMapper.selectById(1);
}

查看是不是从db2数据库查询的,如果是说明成功了。

编写插入测试方法

java 复制代码
@Autowired
private UserMapper userMapper;
@Test
void Save(){
    User user = new User();
    user.setUserName("111");
    user.setUserCode("222");
    userMapper.insert(user);
}

查看是不是从db1数据库写的,如果是说明成功了。因为是db1是主库用于写操作。

分库分表(水平拆分)

这个分库分表和读写分离不一样

读写分离是一样的数据库一样的表(注意我们的读写分离是针对表smbms创建的)

分表:在同一数据库下创建两张订单表,要求结构相同,让id为奇数数据放入smbms_bill_1中,id为偶数数据放入smbms_bill_2中,分开存储数据,查询是合并在一起。

分库分表:在3380与3381下创建smbms01数据库,在3380下创建smbms_bill_1,在3381下创建smbms_bill_2

分库分表和你之前smbms数据库配置的读写分离不一样, 分库分表不需要修改my.ini文件的参数也可使用。

创建数据库

8080数据库

新建数据库为smbms01并执行如下sql语句创建表smbms_bill_1

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `smbms_bill_1`;
CREATE TABLE `smbms_bill_1`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `billCode` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '账单编码',
  `productName` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品名称',
  `productDesc` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品描述',
  `productUnit` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品单位',
  `productCount` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品数量',
  `totalPrice` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品总额',
  `isPayment` int NULL DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
  `createdBy` bigint NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` bigint NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `providerId` bigint NULL DEFAULT NULL COMMENT '供应商ID',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

8081数据库

新建数据库为smbms01并执行如下sql语句创建表smbms_bill_2

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `smbms_bill_2`;
CREATE TABLE `smbms_bill_2`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `billCode` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '账单编码',
  `productName` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品名称',
  `productDesc` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品描述',
  `productUnit` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品单位',
  `productCount` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品数量',
  `totalPrice` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品总额',
  `isPayment` int NULL DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
  `createdBy` bigint NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` bigint NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `providerId` bigint NULL DEFAULT NULL COMMENT '供应商ID',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

结果如下

编写配置文件

修改application.yml

yml 复制代码
server:
  port: 8080
mybatis-plus:
  type-aliases-package: com.hsh.shardingjdbc01.pojo
  configuration: 
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false
spring:
  profiles:
    active: 分库分表  # 改为分库分表继续演示

创建application-分库分表.yml

yml 复制代码
spring:
  shardingsphere:
#    masterslave:  # 分库分表注释掉
#      load-balance-algorithm-type: round_robin #从库 负载均衡轮询  如果读是从两个从库读,为了分担压力所以要负载均衡轮询
#      name: ds  # 数据源 可以随便起名字
#      master-data-source-name: db1 #主库  可以随便起名字
#      slave-data-source-names: db2 #从库,多个可以使用,隔开  可以随便起名字
    datasource:  # 现在有两个数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3380/smbms01
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3381/smbms01
        username: root
        password: root
    sharding: # 从这里配置分库分表
      tables:
        smbms_bill: # 指定表名,此名必须和model中 @TableName(value = "my_table") 一致
        # 因为你的数据库表有两个但是存的数据一样相当于给你的smbms_bill_1和smbms_bill_2起一个统一的名字
          actual-data-nodes: db$->{0..1}.smbms_bill_$->{1..2}  # 这个是db1.smbms_bill_1,db2.smbms_bill_2的省略写法
          key-generator:
            column: id # 主键ID  也可配置其他列
            type: SNOWFLAKE # 生成策略雪花id
          database-strategy: #如果只分表,可不设置
            inline: # 指定表的分片策略
              sharding-column: id #参与分片运算的列名
              algorithmExpression: db$->{id % 2} #分片算法
          table-strategy: # 设置分表
            inline: # 指定表的分片策略
              sharding-column: id
              algorithm-expression: smbms_bill_$->{id % 2 + 1} #分片规则
    props: # 到这里分库分表结束
      sql:
        show: true #打印SQL语句
  main:
    allow-bean-definition-overriding: true # 允许覆盖bean  可以理解为禁用之前的配置的单数据的配置方法

测试

java 复制代码
@Autowired
private BillMapper billMapper;
@Test
public void billMapperInert(){
    Bill bill = new Bill();
    bill.setBillCode("1111");
    bill.setCreatedBy(1);
    bill.setProductName("xxxxxx");
    billMapper.insert(bill);
}

看看是否是按照奇数偶数分开存储

分库分表(垂直拆分)

分别创建数据库smbms02与smbms03

8080端口号的MySQL创建smbms02数据库,并在smbms02中创建表smbms_user

8081端口号的MySQL创建smbms02数据库,并在smbms02中创建表smbms_bill(订单表)

上面这种方式无法进行表连接因为是在两个数据库中

数据库创建

3380

8080端口号的MySQL创建smbms02数据库,并在执行如下命令

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for smbms_user
-- ----------------------------
DROP TABLE IF EXISTS `smbms_user`;
CREATE TABLE `smbms_user`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `userCode` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '用户编码',
  `userName` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '用户名称',
  `userPassword` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '用户密码',
  `gender` int NULL DEFAULT NULL COMMENT '性别(1:女、 2:男)',
  `birthday` date NULL DEFAULT NULL COMMENT '出生日期',
  `phone` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '手机',
  `address` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '地址',
  `userRole` bigint NULL DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)',
  `createdBy` bigint NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` bigint NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` datetime NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1983534085920485379 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of smbms_user
-- ----------------------------
INSERT INTO `smbms_user` VALUES (1, 'admin', '系统管理员', '1234567', 2, '1983-10-10', '13688889999', '北京市海淀区成府路207号', 2, 1, '2013-03-21 16:52:07', NULL, '2025-09-18 14:24:43');
INSERT INTO `smbms_user` VALUES (2, 'liming', '李明', '0000000', 2, '1983-12-10', '13688884457', '北京市东城区前门东大街9号', 2, 1, '2014-12-31 19:52:09', NULL, NULL);
INSERT INTO `smbms_user` VALUES (5, 'hanlubiao', '韩路彪', '0000000', 2, '1984-06-05', '18567542321', '北京市朝阳区北辰中心12号', 2, 1, '2014-12-31 19:52:09', NULL, NULL);
INSERT INTO `smbms_user` VALUES (6, 'zhanghua', '张华', '0000000', 1, '1983-06-15', '13544561111', '北京市海淀区学院路61号', 3, 1, '2013-02-11 10:51:17', NULL, NULL);
INSERT INTO `smbms_user` VALUES (7, 'wangyang', '王洋', '0000000', 2, '1982-12-31', '13444561124', '北京市海淀区西二旗辉煌国际16层', 3, 1, '2014-06-11 19:09:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (8, 'zhaoyan', '赵燕', '0000000', 1, '1986-03-07', '18098764545', '北京市海淀区回龙观小区10号楼', 3, 1, '2016-04-21 13:54:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (10, 'sunlei', '孙磊', '0000000', 2, '1981-01-04', '13387676765', '北京市朝阳区管庄新月小区12楼', 3, 1, '2015-05-06 10:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (11, 'sunxing', '孙兴', '0000000', 2, '1978-03-12', '13367890900', '北京市朝阳区建国门南大街10号', 3, 1, '2016-11-09 16:51:17', NULL, NULL);
INSERT INTO `smbms_user` VALUES (12, 'zhangchen', '张晨', '0000000', 1, '1986-03-28', '18098765434', '朝阳区管庄路口北柏林爱乐三期13号楼', 3, 1, '2016-08-09 05:52:37', 1, '2016-04-14 14:15:36');
INSERT INTO `smbms_user` VALUES (13, 'dengchao', '邓超', '0000000', 2, '1981-11-04', '13689674534', '北京市海淀区北航家属院10号楼', 3, 1, '2016-07-11 08:02:47', NULL, NULL);
INSERT INTO `smbms_user` VALUES (14, 'yangguo', '杨过', '0000000', 2, '1980-01-01', '13388886623', '北京市朝阳区北苑家园茉莉园20号楼', 3, 1, '2015-02-01 03:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (15, 'zhaomin', '赵敏', '0000000', 1, '1987-12-04', '18099897657', '北京市昌平区天通苑3区12号楼', 2, 1, '2015-09-12 12:02:12', NULL, NULL);
INSERT INTO `smbms_user` VALUES (17, '林品如', 'drgdrg', NULL, 2, '2025-09-09', '18754569847', 'hvtyuhguy', 2, NULL, '2025-09-17 18:07:00', NULL, '2025-09-17 18:07:25');

SET FOREIGN_KEY_CHECKS = 1;

3381

8081端口号的MySQL创建smbms02数据库,并在执行如下命令

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for smbms_bill
-- ----------------------------
DROP TABLE IF EXISTS `smbms_bill`;
CREATE TABLE `smbms_bill`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `billCode` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '账单编码',
  `productName` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品名称',
  `productDesc` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品描述',
  `productUnit` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '商品单位',
  `productCount` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品数量',
  `totalPrice` decimal(20, 2) NULL DEFAULT NULL COMMENT '商品总额',
  `isPayment` int NULL DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
  `createdBy` bigint NULL DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `modifyBy` bigint NULL DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `providerId` bigint NULL DEFAULT NULL COMMENT '供应商ID',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of smbms_bill
-- ----------------------------
INSERT INTO `smbms_bill` VALUES (1, 'BILL2016_001', '洗发水、护发素', '日用品-洗发、护发', '瓶', 500.00, 25000.00, 2, 1, '2014-12-14 13:02:03', NULL, NULL, 13);
INSERT INTO `smbms_bill` VALUES (2, 'BILL2016_002', '香皂、肥皂、药皂', '日用品-皂类', '块', 1000.00, 10000.00, 2, 1, '2016-03-23 04:20:40', NULL, NULL, 13);
INSERT INTO `smbms_bill` VALUES (3, 'BILL2016_003', '大豆油', '食品-食用油', '斤', 300.00, 5890.00, 2, 1, '2014-12-14 13:02:03', NULL, NULL, 6);
INSERT INTO `smbms_bill` VALUES (4, 'BILL2016_004', '橄榄油', '食品-进口食用油', '斤', 200.00, 9800.00, 2, 1, '2013-10-10 03:12:13', NULL, NULL, 7);
INSERT INTO `smbms_bill` VALUES (5, 'BILL2016_005', '洗洁精', '日用品-厨房清洁', '瓶', 500.00, 7000.00, 2, 1, '2014-12-14 13:02:03', NULL, NULL, 9);
INSERT INTO `smbms_bill` VALUES (6, 'BILL2016_006', '美国大杏仁', '食品-坚果', '袋', 300.00, 5000.00, 2, 1, '2016-04-14 06:08:09', NULL, NULL, 4);
INSERT INTO `smbms_bill` VALUES (7, 'BILL2016_007', '沐浴液、精油', '日用品-沐浴类', '瓶', 500.00, 23000.00, 1, 1, '2016-07-22 10:10:22', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (8, 'BILL2016_008', '不锈钢盘碗', '日用品-厨房用具', '个', 600.00, 6000.00, 2, 1, '2016-04-14 05:12:13', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (9, 'BILL2016_009', '塑料杯', '日用品-杯子', '个', 350.00, 1750.00, 2, 1, '2016-02-04 11:40:20', NULL, NULL, 14);
INSERT INTO `smbms_bill` VALUES (10, 'BILL2016_010', '豆瓣酱', '食品-调料', '瓶', 200.00, 2000.00, 2, 1, '2013-10-29 05:07:03', NULL, NULL, 8);
INSERT INTO `smbms_bill` VALUES (11, 'BILL2016_011', '海之蓝', '饮料-国酒', '瓶', 50.00, 10000.00, 1, 1, '2016-04-14 16:16:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (12, 'BILL2016_012', '芝华士', '饮料-洋酒', '瓶', 20.00, 6000.00, 1, 1, '2016-09-09 17:00:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (13, 'BILL2016_013', '长城红葡萄酒', '饮料-红酒', '瓶', 60.00, 800.00, 2, 1, '2016-11-14 15:23:00', NULL, NULL, 1);
INSERT INTO `smbms_bill` VALUES (14, 'BILL2016_014', '泰国香米', '食品-大米', '斤', 400.00, 5000.00, 2, 1, '2016-10-09 15:20:00', NULL, NULL, 3);
INSERT INTO `smbms_bill` VALUES (15, 'BILL2016_015', '东北大米', '食品-大米', '斤', 600.00, 4000.00, 2, 1, '2016-11-14 14:00:00', NULL, NULL, 3);
INSERT INTO `smbms_bill` VALUES (16, 'BILL2016_016', '可口可乐', '饮料', '瓶', 2000.00, 6000.00, 2, 1, '2012-03-27 13:03:01', NULL, NULL, 2);
INSERT INTO `smbms_bill` VALUES (17, 'BILL2016_017', '脉动', '饮料', '瓶', 1500.00, 4500.00, 2, 1, '2016-05-10 12:00:00', NULL, NULL, 2);
INSERT INTO `smbms_bill` VALUES (18, 'BILL2016_018', '哇哈哈', '饮料', '瓶', 2000.00, 4000.00, 2, 1, '2015-11-24 15:12:03', NULL, NULL, 2);
INSERT INTO `smbms_bill` VALUES (19, 'BILL2025_001', '醉大转弯', '鸭腿', '只', 15.00, 4500.00, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `smbms_bill` VALUES (20, 'BILL2025_001', '醉大转弯', '鸭腿', '只', 15.00, 4500.00, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `smbms_bill` VALUES (21, 'BILL2025_001', '醉大转弯', NULL, '只', 15.00, 4500.00, NULL, NULL, NULL, NULL, NULL, NULL);

SET FOREIGN_KEY_CHECKS = 1;

结果如下

编写配置文件

修改application.yml

yml 复制代码
server:
  port: 8080
mybatis-plus:
  type-aliases-package: com.hsh.shardingjdbc01.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false 
spring:
  profiles:
    active: 垂直分库分表  # 改为分库分表继续演示

创建application-垂直分库分表.yml

yml 复制代码
spring:
  shardingsphere:
#    masterslave:  # 分库分表注释掉
#      load-balance-algorithm-type: round_robin #从库 负载均衡轮询  如果读是从两个从库读,为了分担压力所以要负载均衡轮询
#      name: ds  # 数据源 可以随便起名字
#      master-data-source-name: db1 #主库  可以随便起名字
#      slave-data-source-names: db2 #从库,多个可以使用,隔开  可以随便起名字
    datasource:  # 现在有两个数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3380/smbms02
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3381/smbms02
        username: root
        password: root
    sharding:
      tables:
        smbms_user:
          actual-data-nodes: db0.smbms_user
        smbms_bill:
          actual-data-nodes: db1.smbms_bill
    props:
      sql:
        show: true #打印SQL语句
  main:
    allow-bean-definition-overriding: true # 允许覆盖bean  可以理解为禁用之前的配置的单数据的配置方法

测试

java 复制代码
@Autowired
private UserMapper userMapper;

@Autowired
private BillMapper billMapper;

@Test
void findBill() {
    billMapper.selectById(1);
}

@Test
void find() {
    userMapper.selectById(1);
}

分别运行上面的发现

user使用的是db0的数据源

bill使用的是db1的数据源

这样说明垂直拆分成功。

相关推荐
JIngJaneIL9 小时前
停车场管理|停车预约管理|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·停车场管理系统
煎蛋学姐9 小时前
SSM儿童福利院管理系统ys9w2d07(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·ssm 框架·儿童福利院管理系统
sg_knight9 小时前
MySQL 空间索引(SPATIAL)详解:地理位置数据的高效查询利器
数据库·mysql·database·索引·关系型数据库·空间索引·spatial
梦子yumeko10 小时前
第五章Langchain4j之基于内存和redis实现聊天持久化
数据库·redis·缓存
IndulgeCui11 小时前
【金仓数据库产品体验官】KSQL Developer Linux版安装使用体验
linux·运维·数据库
一马平川的大草原12 小时前
基于n8n实现数据库多表数据同步
数据库·数据同步·dify·n8n
老华带你飞13 小时前
商城推荐系统|基于SprinBoot+vue的商城推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·商城推荐系统
一 乐13 小时前
物业管理系统|小区物业管理|基于SprinBoot+vue的小区物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端
这周也會开心14 小时前
Spring框架
java·数据库·spring