前面,咱們一共學習了讀寫分離,垂直拆分,垂直拆分+讀寫分離。對應的文章分別以下:node
經過上面的優化,已經能知足大部分的需求了。只有一種狀況須要咱們再次進行優化,那就是單表的數量急劇上升,超過了1千萬以上,這個時候就要對錶進行水平拆分了。github
表的水平拆分是什麼?算法
就是將一個表拆分紅N個表,就像一塊大石頭,搬不動,而後切割成10塊,這樣就能搬的動了。原理是同樣的。spring
除了可以分擔數量的壓力,同時也能分散讀寫請求的壓力,固然這個得看你的分片算法了,合理的算法纔可以讓數據分配均勻並提高性能。sql
今天咱們主要講單庫中進行表的拆分,也就是不分庫,只分表。數據庫
既分庫也分表的操做後面再講,先來一幅圖感覺下未分表:express
而後再來一張圖感覺下已分表:bash
從上圖咱們能夠看出,user表由原來的一個被拆分紅了4個,數據會均勻的分佈在這3個表中,也就是原來的user=user0+user1+user2+user3。
首先咱們須要建立4個用戶表,以下:
CREATE TABLE `user_0`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_1`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_2`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_3`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
複製代碼
分表的數量你須要根據你的數據量也將來幾年的增加來評估。
分表的規則配置:
spring.shardingsphere.datasource.names=master
# 數據源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=master.user_${0..3}
# inline 表達式
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
複製代碼
若是咱們有更復雜的分片需求,能夠自定義分片算法來實現:
# 自定義分表算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.cxytiandi.sharding.algorithm.MyPreciseShardingAlgorithm
複製代碼
算法類:
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
複製代碼
在doSharding方法中你能夠根據參數shardingValue作一些處理,最終返回這條數據須要分片的表名稱便可。
除了單列字段分片,還支持多字段分片,你們能夠本身去看文檔操做一下。
須要分表的進行配置,不須要分表的無需配置,數據庫操做代碼一行都不用改變。
若是咱們要在單庫分表的基礎上,再作讀寫分離,一樣很簡單,只要多配置一個從數據源就能夠了,配置以下:
spring.shardingsphere.datasource.names=master,slave
# 主數據源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 從數據源
spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.slave.username=root
spring.shardingsphere.datasource.slave.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user_${0..3}
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
# 讀寫分離配置
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave
複製代碼
你會發現,到最後這種複雜的分表場景,用框架來解決會很是簡單。至少比你本身經過字段去計算路由的表,去彙總查詢這種形式要好的多。
以爲不錯的記得關注下哦,給個Star吧!