SpringBoot集成Sharding——JDBC分庫分表

Sharding——JDBC

它定位爲輕量級Java框架,在Java的JDBC層提供的額外服務。它使用客戶端直連數據庫,以jar包形式提供服務,無需額外部署和依賴,可理解爲增強版的JDBC驅動,完全兼容JDBC和各種ORM框架。

對比圖:
在這裏插入圖片描述
開發人員只需正常寫查詢、mapper即可、無感知。

分庫分表概念

隨着業務的不斷增長,數據也飛速增長,訪問也隨之變慢,添加從庫、新建索引等很多操作仍嚴重下降,分庫分表需求迫在眉睫。

方案一:
通過提升服務性能來提升數據處理能力,例如:擴容、CPU等,但成本很高。

方案二:
把數據分散在不同數據集中,大表拆成小表、數據落盤到不同庫中,從而使得數據集變小從而提升性能。

  • 垂直分庫
    爲依據,按照業務需求將拆到不同庫中。
    每個的結構不一樣。
    每個的數據不一樣,沒有交集。
    所有庫的並集是全量數據。



場景:
這一步拆分基本是服務化,例如,中間表、字典表、配置表等越來越多,可以將這些表拆分到單獨庫中,甚至可以微服務化。

  • 垂直分表
    字段爲依據,按照字段活躍性拆到不同中。
    每張表結構不一樣。
    每張表數據也不一樣,至少有一列交集用於關聯。
    所有表並集數據是全量數據。



場景:
用戶表中有id、名稱、住址等信息,每次查詢用戶信息時住址字段使次數很低,大字段等單獨拆分一張,從而減少IO提升性能。

  • 水平分庫
    字段爲依據,按照一定策略(hash、range等),將一個中的數據拆分到多個庫中。
    每個庫結構都一樣。
    每個庫數據都不一樣,沒有交集。
    所有庫並集是全量數據。



場景:
庫多了,IO和CPU壓力可以成倍緩解。

  • 水平分表
    字段爲依據,按照一定策略(hash、range等),將一個中的數據拆分到多個表中。
    每張表結構都一樣。
    每張表數據都不一樣,沒有交集。
    所有表並集是全量數據。



場景:
表的數據量少了,SQL執行效率高,IO和CPU壓力可以成倍緩解。

POM文件

	<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!-- Druid連接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

分表配置

新建數據庫名:sharding
新建表名:tbl_dept_1和tbl_dept_2
表結構:

在這裏插入圖片描述

說明:根據dept_id進行分表選擇。

yml文件:

spring:
  main:
    allow-bean-definition-overriding: true
  # 配置Sharding-JDBC的分片策略
  shardingsphere:
    # 配置數據源,給數據源起名g1,g2...此處可配置多數據源
    datasource:
      names: g1
      g1:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "賬號"
        password: "密碼"
    # 配置表的分佈,表的策略
    sharding:
      tables:
        # 表名
        tbl_dept: 
          actual-data-nodes: g1.tbl_dept_${
   
   0..1}
          key-generator:
            # 指定tbl_dept表 主鍵dept_id 生成策略爲 SNOWFLAKE
            column: dept_id
            type: SNOWFLAKE
          table-strategy:
            inline:
              # 指定分片策略 約定dept_id值是偶數添加到tbl_dept_1表,如果dept_id奇數添加到tbl_dept_2表
              sharding-column: dept_id
              algorithm-expression: tbl_dept_${
   
   dept_id % 2 + 1}
    # 打開sql輸出日誌 
    props:
      sql:
        show: true

執行查詢或插入代碼:

TblDept byId = tblDeptService.getById(6);

執行效果日誌:
在這裏插入圖片描述

分庫配置

新建數據庫名:sharding_1,sharding_2
在兩個庫中分別新建表名:tbl_dept_1和tbl_dept_2
表結構:

在這裏插入圖片描述

說明:根據s_id進行分庫選擇,根據dept_id進行分表選擇。

yml文件:

spring:
  main:
    allow-bean-definition-overriding: true
  # 配置Sharding-JDBC的分片策略
  shardingsphere:
    # 配置數據源,給數據源起名g1,g2...此處可配置多數據源
    datasource:
      names: g1,g2
      g1:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding_1?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "賬號"
        password: "密碼"
      g2:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding_2?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "賬號"
        password: "密碼"
    # 配置表的分佈,表的策略
    sharding:
      tables:
        # 表名
        tbl_dept:
          actual-data-nodes: g${
   
   1..2}.tbl_dept_${
   
   1..2}
          # 指定tbl_dept表 主鍵dept_id 生成策略爲 SNOWFLAKE
          key-generator:
            column: dept_id
            type: SNOWFLAKE
          # 指定分片策略 約定dept_id值是偶數添加到tbl_dept_1表,如果dept_id奇數添加到tbl_dept_2表
          database-strategy:
            inline:
              sharding-column: s_id
              algorithm-expression: g${
   
   s_id % 2 + 1}
          table-strategy:
            inline:
              sharding-column: dept_id
              algorithm-expression: tbl_dept_${
   
   dept_id % 2 + 1}

    # 打開sql輸出日誌
    props:
      sql:
        show: true

執行查詢或插入代碼:

	TblDept tblDept = new TblDept();
    tblDept.setDeptId(16L);
    tblDept.setDeptName("分庫");
    tblDept.setSId(6);
    tblDeptService.save(tblDept);

執行效果日誌:
在這裏插入圖片描述

執行查詢或插入代碼:

	TblDept tblDept = new TblDept();
    tblDept.setDeptId(19L);
    tblDept.setDeptName("分庫");
    tblDept.setSId(6);
    tblDeptService.save(tblDept);

執行效果日誌:
在這裏插入圖片描述

轉自:https://blog.csdn.net/s1078229131/article/details/106785894

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章