SpringBoot3和ShardingSphere5框架實現(xiàn)數(shù)據(jù)分庫分表
一、簡介
分庫分表的設計和實現(xiàn)方式,在之前的內容中總結過很多,本文基于 SpringBoot3
和 ShardingSphere5
框架實現(xiàn)數(shù)據(jù)分庫分表的能力;
不得不提 ShardingSphere5
文檔中描述的兩個基本概念:
垂直分片
按照業(yè)務拆分的方式稱為垂直分片,又稱為縱向拆分,它的核心理念是專庫專用。在拆分之前,一個數(shù)據(jù)庫由多個數(shù)據(jù)表構成,每個表對應著不同的業(yè)務。而拆分之后,則是按照業(yè)務將表進行歸類,分布到不同的數(shù)據(jù)庫中,從而將壓力分散至不同的數(shù)據(jù)庫。
水平分片
水平分片又稱為橫向拆分。 相對于垂直分片,它不再將數(shù)據(jù)根據(jù)業(yè)務邏輯分類,而是通過某個字段(或某幾個字段),根據(jù)某種規(guī)則將數(shù)據(jù)分散至多個庫或表中,每個分片僅包含數(shù)據(jù)的一部分。
下面從案例實踐中,看看 ShardingSphere5
框架是如何實現(xiàn)分庫分表的原理;
二、工程搭建
1、工程結構
2、依賴管理
這里只看兩個核心組件的依賴: shardingsphere-jdbc
組件是 5.2.1
版本, mybatis
組件是 3.5.13
版本,在依賴管理中還涉及MySQL和分頁等,并且需要添加很多排除配置,具體見源碼;
<!-- Mybatis組件 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency> <!-- ShardingSphere分庫分表 --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>${shardingsphere.version}</version> </dependency>
三、配置詳解
1、配置文件
此處只展示分庫分表的相關配值,默認數(shù)據(jù)源使用 db_master
庫,注意 tb_order
庫表路由的策略和分片算法的關聯(lián)關系,其他工程配置詳見源碼倉庫;
spring: # 分庫分表配置 shardingsphere: datasource: # 默認數(shù)據(jù)源 sharding: default-data-source-name: db_master names: db_master,db_0,db_1 db_master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/shard_db username: root password: 123456 db_0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/shard_db_0 username: root password: 123456 db_1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/shard_db_1 username: root password: 123456 rules: sharding: tables: # tb_order邏輯 tb_order: actual-data-nodes: db_${0..1}.tb_order_${0..2} # tb_order庫路由 database-strategy: standard: sharding-column: order_id sharding-algorithm-name: database_inline # tb_order表路由 table-strategy: standard: sharding-column: order_id sharding-algorithm-name: table_inline sharding-algorithms: # tb_order庫路由算法 database_inline: type: INLINE props: algorithm-expression: db_${order_id % 2} # tb_order表路由算法 table_inline: type: INLINE props: algorithm-expression: tb_order_${order_id % 3} props: sql-show: true sql-comment-parse-enabled: true
2、配置原理
在配置中需要管理三個數(shù)據(jù)源, shard_db
默認庫,在操作不涉及需要路由的表時默認使用該數(shù)據(jù)源, shard_db_0
和 shard_db_1
是 tb_order
邏輯表的路由庫;
邏輯表 tb_order
整體使用兩個數(shù)據(jù)庫,每個庫建3張結構相同相同的表,在操作 tb_order
數(shù)據(jù)時,會根據(jù) order_id
字段值定位數(shù)據(jù)所屬的分片節(jié)點;
庫路由 db_${0..1}
采用 db_${order_id%2}
的算法; 表路由 tb_order_${0..2}
采用 tb_order_${order_id%3}
的算法;
四、測試案例
1、主庫操作
基于Mybatis持久層框架,實現(xiàn)對 shard_db
默認庫的數(shù)據(jù)操作,注意控制臺的日志打印,可以看到一系列解析邏輯以及庫表節(jié)點的定位,分頁查詢使用PageHelper組件即可;
public class MasterTest { @Autowired private BuyerMapper buyerMapper ; @Autowired private SellerMapper sellerMapper ; @Test public void testBuyerQuery (){ // 主鍵查詢 Buyer buyer = buyerMapper.selectByPrimaryKey(1) ; System.out.println(buyer.getId()+";"+buyer.getBuyerName()); } @Test public void testBuyerInsert (){ // 新增數(shù)據(jù) Buyer buyer = new Buyer() ; buyer.setBuyerName("買家Three"); System.out.println(buyerMapper.insert(buyer)); } @Test public void testBuyerUpdate (){ // 更新數(shù)據(jù) Buyer buyer = buyerMapper.selectByPrimaryKey(3) ; if (buyer != null){ buyer.setBuyerName("Three買家"); System.out.println(buyerMapper.updateByPrimaryKey(buyer)); } } @Test public void testSellerPage (){ // 1、設置分頁和查詢條件 PageHelper.startPage(2,2) ; SellerExample sellerExample = new SellerExample() ; sellerExample.setOrderByClause("id asc"); // 2、查詢數(shù)據(jù) List<Seller> sellerList = sellerMapper.selectByExample(sellerExample) ; // 3、構建分頁實體對象 PageInfo<Seller> pageInfo = new PageInfo<>(sellerList) ; System.out.println(pageInfo); } }
2、分庫操作
在對 tb_order
表執(zhí)行增刪改查時,會根據(jù) order_id
的字段值計算庫表的路由節(jié)點,注意分頁時會查詢所有的分庫和分表,然后匯總查詢的結果;
public class ShardTest { @Autowired private OrderMapper orderMapper ; /** * 寫入100條數(shù)據(jù) */ @Test public void testOrderInsert (){ for (int i=1 ; i<= 100 ; i++){ Order order = new Order(i,i%3+1,i%3+1) ; // orderMapper.insert(order) ; } } @Test public void testOrderQuery (){ Order order = orderMapper.selectByPrimaryKey(5) ; System.out.println(order); } @Test public void testOrderUpdate (){ Order order = orderMapper.selectByPrimaryKey(100) ; if (order != null){ // 原數(shù)據(jù):買家和賣家ID都是2 order.setBuyerId(1); order.setSellerId(3); orderMapper.updateByPrimaryKey(order) ; } } @Test public void testOrderPage (){ // 1、設置分頁和查詢條件 PageHelper.startPage(1,10) ; OrderExample orderExample = new OrderExample() ; orderExample.createCriteria().andBuyerIdEqualTo(2).andSellerIdEqualTo(2); orderExample.setOrderByClause("order_id desc"); // 2、查詢數(shù)據(jù) List<Order> orderList = orderMapper.selectByExample(orderExample) ; // 3、構建分頁實體對象 PageInfo<Order> pageInfo = new PageInfo<>(orderList) ; System.out.println(pageInfo); } }
3、綜合查詢
編寫一個訂單詳情查詢接口,同時使用三個庫構建數(shù)據(jù)結構;如果是基于列表數(shù)據(jù)的檢索,比較常規(guī)做法的是構建ES索引結構,如果沒有搜索的需求,可以在訂單表分頁查詢后去拼接其他結構;
@RestController public class OrderController { @Resource private BuyerMapper buyerMapper ; @Resource private SellerMapper sellerMapper ; @Resource private OrderMapper orderMapper ; /** * 查詢訂單詳情 */ @GetMapping("/order/info/{orderId}") public Map<String,Object> orderInfo (@PathVariable Integer orderId){ Map<String,Object> orderMap = new HashMap<>() ; Order order = orderMapper.selectByPrimaryKey(orderId) ; if (order != null){ orderMap.put("order",order) ; orderMap.put("buyer",buyerMapper.selectByPrimaryKey(order.getBuyerId())) ; orderMap.put("seller",sellerMapper.selectByPrimaryKey(order.getSellerId())) ; } return orderMap ; } }
查看SQL語句
db_master ::: select id, buyer_name from tb_buyer where id = ? ::: [1] db_master ::: select id, seller_name from tb_seller where id = ? ::: [3] db_0 ::: select order_id, seller_id, buyer_id from tb_order_1 where order_id = ? ::: [100]
五、參考源碼
文檔倉庫: https://gitee.com/cicadasmile/butte-java-note 源碼倉庫: https://gitee.com/cicadasmile/butte-spring-parent
到此這篇關于SpringBoot3和ShardingSphere5框架實現(xiàn)數(shù)據(jù)分庫分表的文章就介紹到這了,更多相關SpringBoot3數(shù)據(jù)分庫分表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!