上文中我們實現了SpringBoot整合shardingjdbc+mybatis,其中我們分庫分表的時候選擇的是根據id取模來進行分庫分表。這種分庫分表的形式是比較經典的方式,但是也有很多其他的分表的方式,比如按照年月日分庫分表。本文將詳細講述按照年月日分表
環境准備
在商業開發當中,有一些需求會將幾年的數據放到一個庫里面,但是當前庫里面會建很多表,表明是按照年份和月份來建。我們這里為了演示技術,將會按照一個年份建一個庫,一個年份對應的庫里面按照日期建立365個表。
我這里建立了兩個庫
每個庫對應的表結構如下:
CREATE TABLE `test_20210601` (
`id` bigint(32) NOT NULL,
`year_value` char(4) DEFAULT NULL COMMENT '年份值',
`day_value` char(8) DEFAULT NULL COMMENT '日期值',
`content` varchar(255) DEFAULT NULL COMMENT '內容',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
...
CREATE TABLE `test_20210610` (
`id` bigint(32) NOT NULL,
`year_value` char(4) DEFAULT NULL COMMENT '年份值',
`day_value` char(8) DEFAULT NULL COMMENT '日期值',
`content` varchar(255) DEFAULT NULL COMMENT '內容',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這里近用於展示,所以只建立了10表
配置分庫分表策略
server.port=10080
spring.shardingsphere.datasource.names=ds2021,ds2022
# 配置第一個數據庫
spring.shardingsphere.datasource.ds2021.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds2021.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2021.jdbc-url=jdbc:mysql://localhost:3306/ds2021
spring.shardingsphere.datasource.ds2021.username=root
spring.shardingsphere.datasource.ds2021.password=root
# 配置第二個數據庫
spring.shardingsphere.datasource.ds2022.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds2022.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds2022.jdbc-url=jdbc:mysql://localhost:3306/ds2022
spring.shardingsphere.datasource.ds2022.username=root
spring.shardingsphere.datasource.ds2022.password=root
# 配置test表的分庫策略
spring.shardingsphere.sharding.tables.test.database-strategy.inline.sharding-column=year_value
spring.shardingsphere.sharding.tables.test.database-strategy.inline.algorithm-expression=ds$->{year_value}
# 配置trans_channel的分表策略
spring.shardingsphere.sharding.tables.test.actual-data-nodes=ds$->{2021..2022}.test_$->{20210601..20210610}
spring.shardingsphere.sharding.tables.test.table-strategy.inline.sharding-column=day_value
spring.shardingsphere.sharding.tables.test.table-strategy.inline.algorithm-expression=test_$->{day_value}
# 添加trans_channel表的id生成策略
spring.shardingsphere.sharding.tables.test.key-generator.column=id
spring.shardingsphere.sharding.tables.test.key-generator.type=SNOWFLAKE
測試
按照之前的套路,我們生成點代碼,然后測試一下。這里不再贅述引入shardingjdbc和整合mybatis,如果不太清楚的,可以查看前面兩篇文章
@RestController
@RequestMapping(value = "/test")
public class Test {
@Autowired
private TestService testService;
@GetMapping(value = "/save")
public String save() {
testService.save();
return "success";
}
}
public interface TestService {
void save();
}
public class TestServiceImpl implements TestService {
@Autowired
private TestDao testDao;
@Override
public void save() {
Test test = new Test();
test.setDayValue("20210602");
test.setYearValue("2021");
testDao.save(test);
}
}
public interface TestDao {
int save(Test test);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.echo.shardingjdbc.dao.TestDao">
<resultMap id="BaseResultMap" type="com.echo.shardingjdbc.po.Test">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="year_value" jdbcType="CHAR" property="yearValue"/>
<result column="day_value" jdbcType="CHAR" property="dayValue"/>
<result column="content" jdbcType="VARCHAR" property="content"/>
</resultMap>
<sql id="Base_Column_List">
id, year_value, day_value, content
</sql>
<insert id="save" parameterType="com.echo.shardingjdbc.po.Test">
insert into test (year_value, day_value, content)
values (#{yearValue,jdbcType=CHAR}, #{dayValue,jdbcType=CHAR}, #{content,jdbcType=VARCHAR})
</insert>
</mapper>
調用接口http://localhost:10080/test/save,我們能夠看到最終數據進入了ds2021庫20210602表
我們可以根據我們在配置的時候,定義的規則來更改我們的save值,這樣就能夠有效的將數據存入不同的庫,不同的表。
總結
- 按照年月日分庫分表,關鍵就在於我們配置的時候要用到以某個字段直接作為某個庫或者表的值,如:test_$->{day_value},這代表的就是日期值就是我們表的后綴
- actual-data-nodes描述的是一個真實的取值范圍,如果沒有就會報錯