參考資料:猿天地 https://mp.weixin.qq.com/s/wl8h6LIQUHztVuVbjfsU3Q 作者:尹吉歡
當一個項目量增大,數據表數量增多時,就需要對數據表進行垂直拆分,比如:把會員相關的表放到一個庫里,訂單相關的表放一個庫,商品庫存的表放一個庫里。垂直拆分后,項目中就需要讀取多個數據源,根據表不同動態切換數據源進行操作:
垂直拆分的優點:拆分之后業務規划清晰,數據維護簡單,分擔了數據集中存儲的壓力。
垂直拆分的缺點:缺點也很明顯,多表join查詢無法實現,只能通過接口方式解決,提高了系統復雜度等問題。
技術選型:SpringBoot + Sharding-JDBC + MyBatis
1. 核心Jar包
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- sharding --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC1</version> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <!--阿里數據庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.14</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.60</version> </dependency> </dependencies>
2. yml文件配置
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: db1,db2
# user數據源
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_user?characterEncoding=utf-8
username: ****
password: ****
# order數據源
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_order?characterEncoding=utf-8
username: ****
password: ****
sharding:
tables:
# 綁定表節點
user_info:
actual-data-nodes: db1.user_info
address_info:
actual-data-nodes: db2.order_info
props:
# 開啟SQL顯示,默認false
sql:
show: true
注意:在sharding.tables節點上,要配置每張表所屬的數據庫。
3. 啟動項目測試
2019-12-18 16:19:24.324 INFO 18224 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2019-12-18 16:19:25.470 INFO 18224 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited
執行SQL時,會打印一下日志:
--- [ main] ShardingSphere-SQL : Actual SQL: db1 ::: SELECT id,address,gender,username FROM user_info
--- [ main] ShardingSphere-SQL : Actual SQL: db2 ::: SELECT id,order_no FROM order_info
4. 垂直拆分后的讀寫分離
每個庫增加一個從節點的配置就可以了,然后用master-slave-rules將主從數據源進行綁定。
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: db1,db1slave,db2,db2slave
# user數據源
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_user?characterEncoding=utf-8
username: ****
password: ****
db1slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_user_slave?characterEncoding=utf-8
username: ****
# order數據源
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_order?characterEncoding=utf-8
username: ****
password: ****
db2slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_order?characterEncoding=utf-8
username: ****
password: ****
sharding:
tables:
# 綁定表節點
user_info:
actual-data-nodes: db1.user_info
address_info:
actual-data-nodes: db2.order_info
# 讀寫分離
master-slave-rules:
db1:
master-data-source-name: db1
slave-data-source-names: db1slave
db2:
master-data-source-name: db2
slave-data-source-names: db2slave
props:
# 開啟SQL顯示,默認false
sql:
show: true