參考
yinjihuan 大佬的博客银舱,以及包含github的源代碼喇嘱,6的飛起
http://www.reibang.com/p/0e3905ae6ef2
數(shù)據(jù)分片(分庫(kù)和分表的Springboot版本 配置說明)
http://shardingsphere.io/document/current/cn/manual/sharding-jdbc/configuration/config-spring-boot/
Demo
基于User業(yè)務(wù)的分庫(kù)分表,按照sex字段進(jìn)行分庫(kù)吠卷,按照ID字段進(jìn)行分表王悍,純springboot 配置文件式的指定關(guān)系和策略
https://github.com/huangzhenshi/shardingJdbc-SpringBoot
數(shù)據(jù)庫(kù)分表的概述
- 數(shù)據(jù)庫(kù)分表的目的是提升Mysql查詢的效率,原理類似于數(shù)據(jù)庫(kù)的分區(qū)题画,把一個(gè)大表默辨,根據(jù)業(yè)務(wù)需求的特點(diǎn),拆分成若干個(gè)子表苍息,然后讀寫操作的時(shí)候缩幸,只要操作1個(gè)或者幾個(gè)相關(guān)的子表,而不是全表掃描竞思,從而大大提升查詢的效率表谊。同時(shí)也提升了寫的速度,因?yàn)閷懙臅r(shí)候(比如刪除或者修改)也需要先定位數(shù)據(jù)盖喷。
- 數(shù)據(jù)庫(kù)的分表可以不借助中間件爆办,直接通過編碼的形式實(shí)現(xiàn),例如Mybatis里面SQL课梳,根據(jù)業(yè)務(wù)特點(diǎn)拼子表的表名距辆,但是這種方式的缺點(diǎn)是編程復(fù)雜,而且不適用Hibernate和JPA惦界。
- 數(shù)據(jù)庫(kù)的分表最好是在一個(gè)數(shù)據(jù)庫(kù)里面挑格,避免了分布式事務(wù)的問題,不過理論上也是支持跨庫(kù)的分表
- 可以借助Sharding-Jdbc幫助實(shí)現(xiàn)數(shù)據(jù)庫(kù)的分表漂彤,通過預(yù)先配置表關(guān)系和實(shí)現(xiàn)接口設(shè)定數(shù)據(jù)分配規(guī)則,最終實(shí)現(xiàn)像操作一張表一樣灾搏,操作多個(gè)子表,實(shí)現(xiàn)了類似數(shù)據(jù)庫(kù)分區(qū)的效果狂窑。
配置方式
- 常規(guī)的pom.xml 依賴,只依賴一個(gè)jar包 sharding-jdbc-spring-boot-starter-2.0.0.M3.jar
- 表關(guān)系配置泉哈,多個(gè)子表指定一個(gè)邏輯表破讨,編程的時(shí)候,只要操作邏輯表即可奕纫,中間件封裝了復(fù)雜性
- 配置文件里面指定分表的邏輯,并且指定實(shí)現(xiàn)類匹层,實(shí)現(xiàn)分表邏輯
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>2.0.0.M3</version>
</dependency>
sharding.jdbc.datasource.names=ds_master
sharding.jdbc.datasource.ds_master.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds_master.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds_master.url=jdbc:mysql://localhost:3306/ds_master?characterEncoding=utf-8
sharding.jdbc.datasource.ds_master.username=root
sharding.jdbc.datasource.ds_master.password=123456
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_master.user_${0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.fangjia.sharding.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();
}
}
- 代碼編寫時(shí),和操作一張表一樣升筏,該怎么寫就怎么寫
<insert id="addUser">
INSERT INTO user (id, city, name ) VALUES (#{id},#{city},#{name})
</insert>
<select id="list" resultMap="baseResultMap">
SELECT u.* FROM user u
</select>
<select id="findById" resultMap="baseResultMap">
SELECT u.* FROM user u WHERE u.id=#{id,jdbcType=INTEGER}
</select>
注意事項(xiàng)
使用分表分庫(kù)插入數(shù)據(jù)的時(shí)候,必須先手動(dòng)生成分片鍵(比如ID)您访,否則程序不知道該數(shù)據(jù)要插入到哪個(gè)數(shù)據(jù)庫(kù)的哪張表中。
數(shù)據(jù)庫(kù)分庫(kù)
分庫(kù)可以從物理層面上提升性能洋只,一般用于垂直分片辆沦,把不同的業(yè)務(wù)分在不同的數(shù)據(jù)庫(kù)上识虚,當(dāng)然也支持水平分片肢扯,例如我們的Demo,把User業(yè)務(wù)担锤,按照sex字段進(jìn)行分庫(kù)
分庫(kù)會(huì)引發(fā)分布式事務(wù)的問題
- 配置參考下面的蔚晨,根據(jù)sex字段來進(jìn)行分庫(kù),sex是奇數(shù)進(jìn) ds_1庫(kù)肛循,偶數(shù)進(jìn)ds_0庫(kù)
sharding.jdbc.datasource.names=ds_0,ds_1
sharding.jdbc.datasource.ds_0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds_0.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
sharding.jdbc.datasource.ds_0.username=root
sharding.jdbc.datasource.ds_0.password=123456
sharding.jdbc.datasource.ds_1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds_1.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
sharding.jdbc.datasource.ds_1.username=root
sharding.jdbc.datasource.ds_1.password=123456
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=sex
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds_${sex % 2}
- 插入的時(shí)候铭腕,記得要先指定好 sex字段值
for (long i = 0; i < 100; i++) {
User user = new User();
user.setId(i);
user.setCity("蘇州");
user.setName("小燕兒female");
user.setSex(1);
userService.add(user);
}