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