SpringBoot?快速實(shí)現(xiàn)分庫(kù)分表的2種方式
本文是《分庫(kù)分表ShardingSphere5.x原理與實(shí)戰(zhàn)》系列的第三篇文章,本文將為您介紹 ShardingSphere
的一些基礎(chǔ)特性和架構(gòu)組成,以及在 Springboot
環(huán)境下通過(guò) JAVA編碼
和 Yml配置
兩種方式快速實(shí)現(xiàn)分庫(kù)分表。
一、什么是 ShardingSphere?
shardingsphere
是一款開(kāi)源的分布式關(guān)系型數(shù)據(jù)庫(kù)中間件,為 Apache
的頂級(jí)項(xiàng)目。其前身是 sharding-jdbc
和 sharding-proxy
的兩個(gè)獨(dú)立項(xiàng)目,后來(lái)在 2018 年合并成了一個(gè)項(xiàng)目,并正式更名為 ShardingSphere。
其中 sharding-jdbc 為整個(gè)生態(tài)中最為經(jīng)典和成熟的框架,最早接觸分庫(kù)分表的人應(yīng)該都知道它,是學(xué)習(xí)分庫(kù)分表的最佳入門工具。
如今的 ShardingSphere 已經(jīng)不再是單純代指某個(gè)框架,而是一個(gè)完整的技術(shù)生態(tài)圈,由三款開(kāi)源的分布式數(shù)據(jù)庫(kù)中間件 sharding-jdbc、sharding-proxy 和 sharding-sidecar 所構(gòu)成。前兩者問(wèn)世較早,功能較為成熟,是目前廣泛應(yīng)用的兩個(gè)分布式數(shù)據(jù)庫(kù)中間件,因此在后續(xù)的文章中,我們將重點(diǎn)介紹它們的特點(diǎn)和使用方法。
二、為什么選 ShardingSphere?
為了回答這個(gè)問(wèn)題,我整理了市面上常見(jiàn)的分庫(kù)分表工具,包括 ShardingSphere
、Cobar
、Mycat
、TDDL
、MySQL Fabric
等,并從多個(gè)角度對(duì)它們進(jìn)行了簡(jiǎn)單的比較。
Cobar
Cobar 是阿里巴巴開(kāi)源的一款基于MySQL的分布式數(shù)據(jù)庫(kù)中間件,提供了分庫(kù)分表、讀寫(xiě)分離和事務(wù)管理等功能。它采用輪詢算法和哈希算法來(lái)進(jìn)行數(shù)據(jù)分片,支持分布式分表,但是不支持單庫(kù)分多表。
它以 Proxy
方式提供服務(wù),在阿里內(nèi)部被廣泛使用已開(kāi)源,配置比較容易,無(wú)需依賴其他東西,只需要有Java環(huán)境即可。兼容市面上幾乎所有的 ORM 框架,僅支持 MySQL 數(shù)據(jù)庫(kù),且事務(wù)支持方面比較麻煩。
MyCAT
Mycat
是社區(qū)愛(ài)好者在阿里 Cobar 基礎(chǔ)上進(jìn)行二次開(kāi)發(fā)的,也是一款比較經(jīng)典的分庫(kù)分表工具。它以 Proxy 方式提供服務(wù),支持分庫(kù)分表、讀寫(xiě)分離、SQL路由、數(shù)據(jù)分片等功能。
兼容市面上幾乎所有的 ORM 框架,包括 Hibernate、MyBatis和 JPA等都兼容,不過(guò),美中不足的是它僅支持 MySQL數(shù)據(jù)庫(kù),目前社區(qū)的活躍度相對(duì)較低。
TDDL
TDDL 是阿里巴巴集團(tuán)開(kāi)源的一款分庫(kù)分表解決方案,可以自動(dòng)將SQL路由到相應(yīng)的庫(kù)表上。它采用了垂直切分和水平切分兩種方式來(lái)進(jìn)行分表分庫(kù),并且支持多數(shù)據(jù)源和讀寫(xiě)分離功能。
TDDL 是基于 Java 開(kāi)發(fā)的,支持 MySQL、Oracle 和 SQL Server 數(shù)據(jù)庫(kù),并且可以與市面上 Hibernate、MyBatis等 ORM 框架集成。
不過(guò),TDDL僅支持一些阿里巴巴內(nèi)部的工具和框架的集成,對(duì)于外部公司來(lái)說(shuō)可能相對(duì)有些局限性。同時(shí),其文檔和社區(qū)活躍度相比 ShardingSphere 來(lái)說(shuō)稍顯不足。
Mysql Fabric
MySQL Fabric
是 MySQL 官方提供的一款分庫(kù)分表解決方案,同時(shí)也支持 MySQL其他功能,如高可用、負(fù)載均衡等。它采用了管理節(jié)點(diǎn)和代理節(jié)點(diǎn)的架構(gòu),其中管理節(jié)點(diǎn)負(fù)責(zé)實(shí)時(shí)管理分片信息,代理節(jié)點(diǎn)則負(fù)責(zé)接收并處理客戶端的讀寫(xiě)請(qǐng)求。
它僅支持 MySQL 數(shù)據(jù)庫(kù),并且可以與市面上 Hibernate、MyBatis 等 ORM 框架集成。MySQL Fabric 的文檔相對(duì)來(lái)說(shuō)比較簡(jiǎn)略,而且由于是官方提供的解決方案,其社區(qū)活躍度也相對(duì)較低。
ShardingSphere
ShardingSphere 成員中的 sharding-jdbc 以 JAR
包的形式下提供分庫(kù)分表、讀寫(xiě)分離、分布式事務(wù)等功能,但僅支持 Java 應(yīng)用,在應(yīng)用擴(kuò)展上存在局限性。
因此,ShardingSphere 推出了獨(dú)立的中間件 sharding-proxy,它基于 MySQL協(xié)議實(shí)現(xiàn)了透明的分片和多數(shù)據(jù)源功能,支持各種語(yǔ)言和框架的應(yīng)用程序使用,對(duì)接的應(yīng)用程序幾乎無(wú)需更改代碼,分庫(kù)分表配置可在代理服務(wù)中進(jìn)行管理。
除了支持 MySQL,ShardingSphere還可以支持 PostgreSQL、SQLServer、Oracle等多種主流數(shù)據(jù)庫(kù),并且可以很好地與 Hibernate、MyBatis、JPA等 ORM 框架集成。重要的是,ShardingSphere的開(kāi)源社區(qū)非?;钴S。
如果在使用中出現(xiàn)問(wèn)題,用戶可以在 GitHub 上提交PR并得到快速響應(yīng)和解決,這為用戶提供了足夠的安全感。
產(chǎn)品比較
通過(guò)對(duì)上述的 5 個(gè)分庫(kù)分表工具進(jìn)行比較,我們不難發(fā)現(xiàn),就整體性能、功能豐富度以及社區(qū)支持等方面來(lái)看,ShardingSphere 在眾多產(chǎn)品中優(yōu)勢(shì)還是比較突出的。下邊用各個(gè)產(chǎn)品的主要指標(biāo)整理了一個(gè)表格,看著更加直觀一點(diǎn)。
三、ShardingSphere 成員
ShardingSphere 的主要組成成員為sharding-jdbc
、sharding-proxy
,它們是實(shí)現(xiàn)分庫(kù)分表的兩種不同模式:
sharding-jdbc
它是一款輕量級(jí)Java框架,提供了基于 JDBC 的分庫(kù)分表功能,為客戶端直連模式。使用sharding-jdbc,開(kāi)發(fā)者可以通過(guò)簡(jiǎn)單的配置實(shí)現(xiàn)數(shù)據(jù)的分片,同時(shí)無(wú)需修改原有的SQL語(yǔ)句。支持多種分片策略和算法,并且可以與各種主流的ORM框架無(wú)縫集成。
sharding-proxy
它是基于 MySQL 協(xié)議的代理服務(wù),提供了透明的分庫(kù)分表功能。使用 sharding-proxy 開(kāi)發(fā)者可以將分片邏輯從應(yīng)用程序中解耦出來(lái),無(wú)需修改應(yīng)用代碼就能實(shí)現(xiàn)分片功能,還支持多數(shù)據(jù)源和讀寫(xiě)分離等高級(jí)特性,并且可以作為獨(dú)立的服務(wù)運(yùn)行。
四、快速實(shí)現(xiàn)
我們先使用sharding-jdbc
來(lái)快速實(shí)現(xiàn)分庫(kù)分表。相比于 sharding-proxy,sharding-jdbc 適用于簡(jiǎn)單的應(yīng)用場(chǎng)景,不需要額外的環(huán)境搭建等。下邊主要基于 SpringBoot 的兩種方式來(lái)實(shí)現(xiàn)分庫(kù)分表,一種是通過(guò)YML配置
方式,另一種則是通過(guò)純Java編碼
方式(不可并存)。在后續(xù)章節(jié)中,我們會(huì)單獨(dú)詳細(xì)介紹如何使用sharding-proxy
以及其它高級(jí)特性。
ShardingSphere 官網(wǎng)地址:https://shardingsphere.apache.org/
準(zhǔn)備工作
在開(kāi)始實(shí)現(xiàn)之前,需要對(duì)數(shù)據(jù)庫(kù)和表的拆分規(guī)則進(jìn)行明確。以對(duì)t_order
表進(jìn)行分庫(kù)分表拆分為例,具體地,我們將 t_order 表拆分到兩個(gè)數(shù)據(jù)庫(kù)中,分別為db1
和db2
,每個(gè)數(shù)據(jù)庫(kù)又將該表拆分為三張表,分別為t_order_1
、t_order_2
和t_order_3
。
db0
├── t_order_0
├── t_order_1
└── t_order_2
db1
├── t_order_0
├── t_order_1
└── t_order_2
JAR包引入
引入必要的 JAR 包,其中最重要的是shardingsphere-jdbc-core-spring-boot-starter
和mysql-connector-java
這兩個(gè)。為了保證功能的全面性和兼容性,以及避免因低版本包導(dǎo)致的不必要錯(cuò)誤和調(diào)試工作,我選擇的包版本都較高。
shardingsphere-jdbc-core-spring-boot-starter 是 ShardingSphere 框架的核心組件,提供了對(duì) JDBC 的分庫(kù)分表支持;而 mysql-connector-java 則是 MySQL JDBC 驅(qū)動(dòng)程序的實(shí)現(xiàn),用于連接MySQL數(shù)據(jù)庫(kù)。除此之外,我使用了JPA
作為持久化工具還引入了相應(yīng)的依賴包。
<!-- jpa持久化工具 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.7.6</version> </dependency> <!-- 必須引入的包 mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> </dependency> <!-- 必須引入的包 ShardingSphere --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.2.0</version> </dependency>
YML配置
我個(gè)人是比較推薦使用YML配置方式來(lái)實(shí)現(xiàn) sharding-jdbc 分庫(kù)分表的,使用YML配置方式不僅可以讓分庫(kù)分表的實(shí)現(xiàn)更加簡(jiǎn)單、高效、可維護(hù),也更符合 SpringBoot的開(kāi)發(fā)規(guī)范。
在 src/main/resources/application.yml 路徑文件下添加以下完整的配置,即可實(shí)現(xiàn)對(duì)t_order
表的分庫(kù)分表,接下來(lái)拆解看看每個(gè)配置模塊都做了些什么。
spring: shardingsphere: # 數(shù)據(jù)源配置 datasource: # 數(shù)據(jù)源名稱,多數(shù)據(jù)源以逗號(hào)分隔 names: db0,db1 db0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingsphere-db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 db1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingsphere-db0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 # 分片規(guī)則配置 rules: sharding: # 分片算法配置 sharding-algorithms: database-inline: # 分片算法類型 type: INLINE props: # 分片算法的行表達(dá)式(算法自行定義,此處為方便演示效果) algorithm-expression: db$->{order_id > 4?1:0} table-inline: # 分片算法類型 type: INLINE props: # 分片算法的行表達(dá)式 algorithm-expression: t_order_$->{order_id % 4} tables: # 邏輯表名稱 t_order: # 行表達(dá)式標(biāo)識(shí)符可以使用 ${...} 或 $->{...},但前者與 Spring 本身的屬性文件占位符沖突,因此在 Spring 環(huán)境中使用行表達(dá)式標(biāo)識(shí)符建議使用 $->{...} actual-data-nodes: db${0..1}.t_order_${0..3} # 分庫(kù)策略 database-strategy: standard: # 分片列名稱 sharding-column: order_id # 分片算法名稱 sharding-algorithm-name: database-inline # 分表策略 table-strategy: standard: # 分片列名稱 sharding-column: order_id # 分片算法名稱 sharding-algorithm-name: table-inline # 屬性配置 props: # 展示修改以后的sql語(yǔ)句 sql-show: true
以下是 shardingsphere
多數(shù)據(jù)源信息的配置,其中的 names
表示需要連接的數(shù)據(jù)庫(kù)別名列表,每添加一個(gè)數(shù)據(jù)庫(kù)名就需要新增一份對(duì)應(yīng)的數(shù)據(jù)庫(kù)連接配置。
spring: shardingsphere: # 數(shù)據(jù)源配置 datasource: # 數(shù)據(jù)源名稱,多數(shù)據(jù)源以逗號(hào)分隔 names: db0,db1 db0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingsphere-db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 db1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://127.0.0.1:3306/shardingsphere-db0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456
rules
節(jié)點(diǎn)下為分片規(guī)則的配置,sharding-algorithms
節(jié)點(diǎn)為自定義的分片算法模塊,分片算法可以在后邊配置表的分片規(guī)則時(shí)被引用,其中:
database-inline
:自定義的分片算法名稱;type
:該分片算法的類型,這里先以 inline 為例,后續(xù)會(huì)有詳細(xì)章節(jié)介紹;props
:指定該分片算法的具體內(nèi)容,其中algorithm-expression
是該分片算法的表達(dá)式,即根據(jù)分片鍵值計(jì)算出要訪問(wèn)的真實(shí)數(shù)據(jù)庫(kù)名或表名,。
db$->{order_id % 2}
這種為 Groovy 語(yǔ)言表達(dá)式,表示對(duì)分片鍵 order_id
進(jìn)行取模,根據(jù)取模結(jié)果計(jì)算出db0、db1,分表的表達(dá)式同理。
spring: shardingsphere: # 規(guī)則配置 rules: sharding: # 分片算法配置 sharding-algorithms: database-inline: # 分片算法類型 type: INLINE props: # 分片算法的行表達(dá)式(算法自行定義,此處為方便演示效果) algorithm-expression: db$->{order_id % 2} table-inline: # 分片算法類型 type: INLINE props: # 分片算法的行表達(dá)式 algorithm-expression: t_order_$->{order_id % 3}
tables
節(jié)點(diǎn)定義了邏輯表名t_order
的分庫(kù)分表規(guī)則。actual-data-nodes
用于設(shè)置物理數(shù)據(jù)節(jié)點(diǎn)的數(shù)量。
db${0..1}.t_order_${0..3}
表達(dá)式意思此邏輯表在不同數(shù)據(jù)庫(kù)實(shí)例中的分布情況,如果只想單純的分庫(kù)或者分表,可以調(diào)整表達(dá)式,分庫(kù)db${0..1}
、分表t_order_${0..3}
。
db0
├── t_order_0
├── t_order_1
└── t_order_2
db1
├── t_order_0
├── t_order_1
└── t_order_2
spring: shardingsphere: # 規(guī)則配置 rules: sharding: tables: # 邏輯表名稱 t_order: # 行表達(dá)式標(biāo)識(shí)符可以使用 ${...} 或 $->{...},但前者與 Spring 本身的屬性文件占位符沖突,因此在 Spring 環(huán)境中使用行表達(dá)式標(biāo)識(shí)符建議使用 $->{...} actual-data-nodes: db${0..1}.t_order_${0..3} # 分庫(kù)策略 database-strategy: standard: # 分片列名稱 sharding-column: order_id # 分片算法名稱 sharding-algorithm-name: database-inline # 分表策略 table-strategy: standard: # 分片列名稱 sharding-column: order_id # 分片算法名稱 sharding-algorithm-name: table-inline
database-strategy
和 table-strategy
分別設(shè)置了分庫(kù)和分表策略;
sharding-column
表示根據(jù)表的哪個(gè)列(分片鍵)進(jìn)行計(jì)算分片路由到哪個(gè)庫(kù)、表中;
sharding-algorithm-name
表示使用哪種分片算法對(duì)分片鍵進(jìn)行運(yùn)算處理,這里可以引用剛才自定義的分片算法名稱使用。
props
節(jié)點(diǎn)用于設(shè)置其他的屬性配置,比如:sql-show
表示是否在控制臺(tái)輸出解析改造后真實(shí)執(zhí)行的 SQL語(yǔ)句以便進(jìn)行調(diào)試。
spring: shardingsphere: # 屬性配置 props: # 展示修改以后的sql語(yǔ)句 sql-show: true
跑個(gè)單測(cè)在向數(shù)據(jù)庫(kù)中插入 10 條數(shù)據(jù)時(shí),發(fā)現(xiàn)數(shù)據(jù)已經(jīng)相對(duì)均勻地插入到了各個(gè)分片中。
JAVA 編碼
如果您不想通過(guò) yml 配置文件實(shí)現(xiàn)自動(dòng)裝配,也可以使用 ShardingSphere 的 API 實(shí)現(xiàn)相同的功能。使用 API 完成分片規(guī)則和數(shù)據(jù)源的配置,優(yōu)勢(shì)在于更加靈活、可定制性強(qiáng)的特點(diǎn),方便進(jìn)行二次開(kāi)發(fā)和擴(kuò)展。
下邊是純JAVA編碼方式實(shí)現(xiàn)分庫(kù)分表的完整代碼。
@Configuration public class ShardingConfiguration { /** * 配置分片數(shù)據(jù)源 * 公眾號(hào):程序員小富 */ @Bean public DataSource getShardingDataSource() throws SQLException { Map<String, DataSource> dataSourceMap = new HashMap<>(); dataSourceMap.put("db0", dataSource1()); dataSourceMap.put("db1", dataSource2()); // 分片rules規(guī)則配置 ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.setShardingAlgorithms(getShardingAlgorithms()); // 配置 t_order 表分片規(guī)則 ShardingTableRuleConfiguration orderTableRuleConfig = new ShardingTableRuleConfiguration("t_order", "db${0..1}.t_order_${0..2}"); orderTableRuleConfig.setTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "table-inline")); orderTableRuleConfig.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "database-inline")); shardingRuleConfig.getTables().add(orderTableRuleConfig); // 是否在控制臺(tái)輸出解析改造后真實(shí)執(zhí)行的 SQL Properties properties = new Properties(); properties.setProperty("sql-show", "true"); // 創(chuàng)建 ShardingSphere 數(shù)據(jù)源 return ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(shardingRuleConfig), properties); } /** * 配置數(shù)據(jù)源1 * 公眾號(hào):程序員小富 */ public DataSource dataSource1() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/shardingsphere-db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"); dataSource.setUsername("root"); dataSource.setPassword("123456"); return dataSource; } /** * 配置數(shù)據(jù)源2 * 公眾號(hào):程序員小富 */ public DataSource dataSource2() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/shardingsphere-db0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"); dataSource.setUsername("root"); dataSource.setPassword("123456"); return dataSource; } /** * 配置分片算法 * 公眾號(hào):程序員小富 */ private Map<String, AlgorithmConfiguration> getShardingAlgorithms() { Map<String, AlgorithmConfiguration> shardingAlgorithms = new LinkedHashMap<>(); // 自定義分庫(kù)算法 Properties databaseAlgorithms = new Properties(); databaseAlgorithms.setProperty("algorithm-expression", "db$->{order_id % 2}"); shardingAlgorithms.put("database-inline", new AlgorithmConfiguration("INLINE", databaseAlgorithms)); // 自定義分表算法 Properties tableAlgorithms = new Properties(); tableAlgorithms.setProperty("algorithm-expression", "t_order_$->{order_id % 3}"); shardingAlgorithms.put("table-inline", new AlgorithmConfiguration("INLINE", tableAlgorithms)); return shardingAlgorithms; } }
ShardingSphere
的分片核心配置類 ShardingRuleConfiguration
,它主要用來(lái)加載分片規(guī)則、分片算法、主鍵生成規(guī)則、綁定表、廣播表等核心配置。我們將相關(guān)的配置信息 set到配置類,并通過(guò)createDataSource
創(chuàng)建并覆蓋 DataSource
,最后注入Bean。
使用Java編碼方式只是將 ShardingSphere 預(yù)知的加載配置邏輯自己手動(dòng)實(shí)現(xiàn)了一遍,兩種實(shí)現(xiàn)方式比較下來(lái),還是推薦使用YML配置方式來(lái)實(shí)現(xiàn) ShardingSphere
的分庫(kù)分表功能,相比于Java編碼,YML配置更加直觀和易于理解,開(kāi)發(fā)者可以更加專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而不需要過(guò)多關(guān)注底層技術(shù)細(xì)節(jié)。
@Getter @Setter public final class ShardingRuleConfiguration implements DatabaseRuleConfiguration, DistributedRuleConfiguration { // 分表配置配置 private Collection<ShardingTableRuleConfiguration> tables = new LinkedList<>(); // 自動(dòng)分片規(guī)則配置 private Collection<ShardingAutoTableRuleConfiguration> autoTables = new LinkedList<>(); // 綁定表配置 private Collection<String> bindingTableGroups = new LinkedList<>(); // 廣播表配置 private Collection<String> broadcastTables = new LinkedList<>(); // 默認(rèn)的分庫(kù)策略配置 private ShardingStrategyConfiguration defaultDatabaseShardingStrategy; // 默認(rèn)的分表策略配置 private ShardingStrategyConfiguration defaultTableShardingStrategy; // 主鍵生成策略配置 private KeyGenerateStrategyConfiguration defaultKeyGenerateStrategy; private ShardingAuditStrategyConfiguration defaultAuditStrategy; // 默認(rèn)的分片鍵 private String defaultShardingColumn; // 自定義的分片算法 private Map<String, AlgorithmConfiguration> shardingAlgorithms = new LinkedHashMap<>(); // 主鍵生成算法 private Map<String, AlgorithmConfiguration> keyGenerators = new LinkedHashMap<>(); private Map<String, AlgorithmConfiguration> auditors = new LinkedHashMap<>(); }
經(jīng)過(guò)查看控制臺(tái)打印的真實(shí) SQL日志,發(fā)現(xiàn)在使用 ShardingSphere
進(jìn)行數(shù)據(jù)插入時(shí),其內(nèi)部實(shí)現(xiàn)會(huì)先根據(jù)分片鍵 order_id
查詢記錄是否存在。如果記錄不存在,則執(zhí)行插入操作;如果記錄已存在,則進(jìn)行更新操作??此浦粫?huì)執(zhí)行10條插入SQL,但實(shí)際上需要執(zhí)行20條SQL語(yǔ)句,多少會(huì)對(duì)數(shù)據(jù)庫(kù)的性能產(chǎn)生一定的影響。
功能挺簡(jiǎn)單的,但由于不同版本的 ShardingSphere 的 API 變化較大,網(wǎng)上類似的資料太不靠譜,本來(lái)想著借助 GPT 快點(diǎn)實(shí)現(xiàn)這段代碼,結(jié)果差點(diǎn)和它干起來(lái),最后還是扒了扒看了源碼完成的。
默認(rèn)數(shù)據(jù)源
可能有些小伙伴會(huì)有疑問(wèn),對(duì)于已經(jīng)設(shè)置了分片規(guī)則的t_order
表可以正常操作數(shù)據(jù),如果我們的t_user
表沒(méi)有配置分庫(kù)分表規(guī)則,那么在執(zhí)行插入操作時(shí)會(huì)發(fā)生什么呢?
仔細(xì)看了下官方的技術(shù)文檔,其實(shí)已經(jīng)回答了小伙伴這個(gè)問(wèn)題,如果只有部分?jǐn)?shù)據(jù)庫(kù)分庫(kù)分表,是否需要將不分庫(kù)分表的表也配置在分片規(guī)則中?官方回答:不需要。
我們創(chuàng)建一張t_user
表,并且不對(duì)其進(jìn)行任何分片規(guī)則的配置。在我的印象中沒(méi)有通過(guò)設(shè)置 default-data-source-name
默認(rèn)的數(shù)據(jù)源,操作未分片的表應(yīng)該會(huì)報(bào)錯(cuò)的!
我們向t_user
嘗試插入一條數(shù)據(jù),結(jié)果居然成功了?翻了翻庫(kù)表發(fā)現(xiàn)數(shù)據(jù)只被插在了 db1 庫(kù)里,說(shuō)明沒(méi)有走廣播路由。
shardingsphere-jdbc 5.x版本
移除了原本的默認(rèn)數(shù)據(jù)源配置,自動(dòng)使用了默認(rèn)數(shù)據(jù)源的規(guī)則,為驗(yàn)證我多增加了數(shù)據(jù)源,嘗試性的調(diào)整了db2
、db0
、db1
的順序,再次插入數(shù)據(jù),這回記錄被插在了 db2
庫(kù),反復(fù)試驗(yàn)初步得出結(jié)論。
未分片的表默認(rèn)會(huì)使用第一個(gè)數(shù)據(jù)源作為默認(rèn)數(shù)據(jù)源,也就是 datasource.names
第一個(gè)。
spring: shardingsphere: # 數(shù)據(jù)源配置 datasource: # 數(shù)據(jù)源名稱,多數(shù)據(jù)源以逗號(hào)分隔 names: db2 , db1 , db0
總結(jié)
本期我們對(duì) shardingsphere 做了簡(jiǎn)單的介紹,并使用 yml 和 Java編碼的方式快速實(shí)現(xiàn)了分庫(kù)分表功能,接下來(lái)會(huì)按照文首的思維導(dǎo)圖的功能逐一實(shí)現(xiàn)。
下期文章將是《分庫(kù)分表ShardingSphere5.x原理與實(shí)戰(zhàn)》系列的第四篇,《分庫(kù)分表默認(rèn)分片策略、廣播表、綁定表一網(wǎng)打盡》。
到此這篇關(guān)于SpringBoot 2 種方式快速實(shí)現(xiàn)分庫(kù)分表,輕松拿捏!的文章就介紹到這了,更多相關(guān)SpringBoot 分庫(kù)分表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫(kù)分表
- SpringBoot?如何使用sharding?jdbc進(jìn)行分庫(kù)分表
- SpringBoot實(shí)現(xiàn)分庫(kù)分表
- SpringBoot整合sharding-jdbc實(shí)現(xiàn)自定義分庫(kù)分表的實(shí)踐
- SpringBoot整合sharding-jdbc實(shí)現(xiàn)分庫(kù)分表與讀寫(xiě)分離的示例
- springboot整合shardingjdbc實(shí)現(xiàn)分庫(kù)分表最簡(jiǎn)單demo
- springboot jpa分庫(kù)分表項(xiàng)目實(shí)現(xiàn)過(guò)程詳解
- Springboot2.x+ShardingSphere實(shí)現(xiàn)分庫(kù)分表的示例代碼
- SpringBoot 2.0 整合sharding-jdbc中間件實(shí)現(xiàn)數(shù)據(jù)分庫(kù)分表
- SpringBoot3和ShardingSphere5框架實(shí)現(xiàn)數(shù)據(jù)分庫(kù)分表
相關(guān)文章
Spring Boot Gradle發(fā)布war到tomcat的方法示例
本篇文章主要介紹了Spring Boot Gradle發(fā)布war到tomcat的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Springboot詳解RocketMQ實(shí)現(xiàn)廣播消息流程
RocketMQ作為一款純java、分布式、隊(duì)列模型的開(kāi)源消息中間件,支持事務(wù)消息、順序消息、批量消息、定時(shí)消息、消息回溯等,本篇我們了解如何實(shí)現(xiàn)廣播消息2022-06-06一文簡(jiǎn)介Java中BlockingQueue阻塞隊(duì)列
本文主要介紹了一文簡(jiǎn)介Java中BlockingQueue阻塞隊(duì)列,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06MyBatis實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)表分月存儲(chǔ)
本文主要介紹了MyBatis實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)表分月存儲(chǔ),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03SpringCloud Alibaba項(xiàng)目實(shí)戰(zhàn)之nacos-server服務(wù)搭建過(guò)程
Nacos 是阿里巴巴推出來(lái)的一個(gè)新開(kāi)源項(xiàng)目,這是一個(gè)更易于構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺(tái)。本章節(jié)重點(diǎn)給大家介紹SpringCloud Alibaba項(xiàng)目實(shí)戰(zhàn)之nacos-server服務(wù)搭建過(guò)程,感興趣的朋友一起看看吧2021-06-06java 獲取項(xiàng)目文件路徑實(shí)現(xiàn)方法
以下是對(duì)java中獲取項(xiàng)目文件路徑的實(shí)現(xiàn)方法進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09EasyExcel工具讀取Excel空數(shù)據(jù)行問(wèn)題的解決辦法
EasyExcel是阿里巴巴開(kāi)源的一個(gè)excel處理框架,以使用簡(jiǎn)單,節(jié)省內(nèi)存著稱,下面這篇文章主要給大家介紹了關(guān)于EasyExcel工具讀取Excel空數(shù)據(jù)行問(wèn)題的解決辦法,需要的朋友可以參考下2022-08-08