Java中使用Shardingsphere-JDBC進行分庫分表的使用方法(精簡)


1.pom.xml中添加依賴

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

<!--相關基礎依賴-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>


2. application.yml中添加相關配

2.1 不分庫分表的基礎連接配置

 spring:
  shardingsphere:
   datasource:
    names: s1
    s1:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3306/mydb?serverTimezone=GMT%2B8
     username: root
     password: root
   props:
    sql:

     #是否打印sql
     show: true

*注意:這樣配的話,跟操作單庫單表的數據源配置效果一樣


2.2 不分庫但分表的連接配置

 spring:

  shardingsphere:
   datasource:
    names: s1
    s1:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3306/mydb?serverTimezone=GMT%2B8
     username: root
     password: root
   props:
    sql:
     show: true
   sharding:
    #分表
    tables:
     #參與分表的表名(虛擬表名)
     test:
      #分幾個表,這里是兩個,test_1和test_2
      actual-data-nodes: s1.test_$->{1..2}
      key-generator:
       #主鍵
       column: tid
       #主鍵填值,雪花
       type: SNOWFLAKE
      table-strategy:
       #主鍵分表路由策略
       inline:
        sharding-column: tid
        #這里采用偶數鍵值去test_1表,奇數鍵值去test_2表
        algorithm-expression: test_$->{tid%2+1}

2.3 分庫分表的連接配置

 spring:

  shardingsphere:
   datasource:
    names: s1,s2
    s1:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3306/mydb1?serverTimezone=GMT%2B8
     username: root
     password: root

    s2:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3307/mydb2?serverTimezone=GMT%2B8
     username: root
     password: root
   props:
    sql:
     show: true
   sharding:
    #分表
    tables:
     #參與分表的表名(虛擬表名)
     test:
      #分庫分表關鍵
      actual-data-nodes: s$->{1..2}.test_$->{1..2}
      key-generator:
       #主鍵
       column: tid
       #主鍵填值,雪花
       type: SNOWFLAKE
      table-strategy:
       #主鍵分表路由策略
       inline:
        sharding-column: tid
        #這里采用偶數鍵值去test_1表,奇數鍵值去test_2表
        algorithm-expression: test_$->{tid%2+1}

      data-strategy:
       #主鍵分庫路由策略
       inline:
        sharding-column: tid
        #這里采用偶數鍵值去s1庫,奇數鍵值去s2庫
        algorithm-expression: s_$->{tid%2+1}

 

2.3 讀寫分離(mysql實現配置了主從架構)分庫分表的連接配置

 spring:

  shardingsphere:
   datasource:
    names: m1,s1
    m1:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3306/mydb?serverTimezone=GMT%2B8
     username: root
     password: root

    s1:
     type: com.alibaba.druid.pool.DruidDataSource
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://localhost:3307/mydb?serverTimezone=GMT%2B8
     username: root
     password: root
   props:
    sql:
     show: true
   sharding:
    #分表
    tables:
     #參與分表的表名(虛擬表名)
     test:
      #分庫分表關鍵
      actual-data-nodes: ms0.test_$->{1..2}
      key-generator:
       #主鍵
       column: tid
       #主鍵填值,雪花
       type: SNOWFLAKE
      table-strategy:
       #主鍵分表路由策略
       inline:
        sharding-column: tid
        #這里采用偶數鍵值去test_1表,奇數鍵值去test_2表
        algorithm-expression: test_$->{tid%2+1}

    #主從規則

    master-slave-rules:

     #規則一,名字隨意,我這里用ms0表示

     ms0:

      master-data-source-name: m0

      #這里可以看出從庫可以配多個

      slave-data-source-names[0]: s0

      

 3.分庫分表路由策略

 shardingsphere為我們提供了以下幾種策略類型:

  inline(內聯),standard(標准),complex(復雜),hint(強制)

 

3.1 inline

#分片策略(test是我們的邏輯表,這里對應實際表test_1和test_2)

spring.shardingsphere.sharding.tables.test.table-strategy.inline.sharding-column=tid
spring.shardingsphere.sharding.tables.test.table-strategy.inline.algorithm-expression=test_$->{tid%2+1}
#分庫策略
spring.shardingsphere.sharding.tables.test.database-strategy.inline.sharding-column=tid
spring.shardingsphere.sharding.tables.test.database-strategy.inline.algorithm-expression=s$->{tid%2+1}

*注:只支持分片主鍵的精確路由,不支持范圍查詢、模糊查詢、聯表查詢。

 

3.2 standard(需要實現PreciseShardingAlgorithm和RangeShardingAlgorithm接口)

#分片策略

spring.shardingsphere.sharding.tables.test.table-strategy.standard.sharding-column=tid
spring.shardingsphere.sharding.tables.test.table-strategy.standard.precise-algorithm-class-name=com.shardingDemo.algorithem.MyPreciseTableShardingAlgorithm
spring.shardingsphere.sharding.tables.test.table-strategy.standard.range-algorithm-class-name=com.shardingDemo.algorithem.MyRangeTableShardingAlgorithm
#分庫策略

spring.shardingsphere.sharding.tables.test.database-strategy.standard.sharding-column=tid
spring.shardingsphere.sharding.tables.test.database-strategy.standard.precise-algorithm-class-name=com.shardingDemo.algorithem.MyPreciseDSShardingAlgorithm
spring.shardingsphere.sharding.tables.test.database-strategy.standard.range-algorithm-class-name=com.shardingDemo.algorithem.MyRangeDSShardingAlgorithm

*注:需要定制實現精確路由和范圍路由的邏輯類,也就是自己編碼路由邏輯。

 

3.3 complex(需要實現ComplexKeysShardingAlgorithm接口)

#分片策略(這里用了兩個表的主鍵tid和uid)

spring.shardingsphere.sharding.tables.test.table-strategy.complex.sharding-columns= tid, uid
spring.shardingsphere.sharding.tables.test.table-strategy.complex.algorithm-class-name=com.shardingDemo.algorithem.MyComplexTableShardingAlgorithm

#分庫策略(這里用了兩個表的主鍵tid和uid)
spring.shardingsphere.sharding.tables.test.database-strategy.complex.sharding-columns=tid, uid
spring.shardingsphere.sharding.tables.test.database-strategy.complex.algorithm-class-name=com.shardingDemo.algorithem.MyComplexDSShardingAlgorithm

*注:需要定制實現多表關聯路由邏輯類。

 

3.4 hint(需要實現HintShardingAlgorithm接口)

 spring.shardingsphere.sharding.tables.course.table-strategy.hint.algorithm-class-name=com.shardingDemo.algorithem.MyHintTableShardingAlgorithm

*注:需要定制實現指定路由邏輯類,在使用查詢語句時加上此規則后,可以去指定庫表查詢數據。

用法舉例:  

  HintManager hintManager = HintManager.getInstance();
  hintManager.addTableShardingValue("test", 2);  //去test_2表查數據
  List<Test> tests= testMapper.selectList(null);
  tests.forEach(test-> System.out.println(test));
  hintManager.close();

 

4. 關於廣播表和綁定表

 

4.1 廣播表

分庫以后每個庫都有的全數據表這種表的數據一般變動很小,例如:字典表和狀態表,這些表的數據在每一個庫里都應該是一致的。

spring.shardingsphere.sharding.broadcast-tables=t_dict
spring.shardingsphere.sharding.tables.t_dict.key-generator.column=dict_id
spring.shardingsphere.sharding.tables.t_dict.key-generator.type=SNOWFLAKE

 

4.2 綁定表

當我們的查詢條件依賴廣播表時,也就是某邏輯表的字段的值依賴於一張廣播表時,為避免聯表查詢產生笛卡爾積,則需要使用綁定規則。

spring.shardingsphere.sharding.binding-tables[0]=test,t_dict

 

5. 總結

使用分庫分表的初衷是為了解決海量數據查詢較慢的問題,列入當一張表的數據記錄超過500萬條或者單表容量大於2GB是則需要考慮分庫分表,

但是分庫分表會帶來許多設計上和生產上的麻煩,增加邏輯復雜度和查詢語句的使用限制,所以不要濫用分庫分表,能不分就不分。另外分庫分

表最好是在程序設計之初提前預估當前業務的數據增長量是否需要設計成分庫分表架構,如果某個業務表比如訂單表,他的增常量肯定每年都很

大,這個時候這張業務表就需要設計成分表,而用戶表這種業務表起初可能增長勢頭很猛,但是經過兩三年,數據基本上就穩定了,不會有較大

變動,那么,可以考慮設計此表時將表字段進行垂直切割,將常用字段放進用戶表,而不常用字段放進用戶關聯表,但不做分表或分庫。總之,

這是一個考驗你業務和程序架構雙項經驗的事情。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM