1.背景
在订单、流水等场景下,与时间段关联最紧密的大数据业务,单表很容易就超过了千万级别,这时MySQL的性能大打折扣,利用ShardingSphere我们可以完成按照时间分库分表,从而降低单表的数据量。
2.实现
其他代码参考前一篇文章
spring:
shardingsphere:
datasource:
names: ds1
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ds1?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
sharding:
tables:
sensor_xmz:
actualDataNodes: ds$->{2021...2025}.sensor_xmz_$->{1..4}
# 分库策略
databaseStrategy:
standard:
shardingColumn: create_time
preciseAlgorithmClassName: com.zym.config.PreciseModuloDatabaseShardingAlgorithm
# 分表策略
tableStrategy:
standard:
shardingColumn: create_time
preciseAlgorithmClassName: com.zym.config.PreciseModuloTableShardingAlgorithm
props:
sql:
show: true
main:
allow-bean-definition-overriding: true
精确分片,则需要自己实现分片类
PreciseModuloDatabaseShardingAlgorithm.java
package com.zym.config;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
public class PreciseModuloDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
//配置的分库分片的sharding-column对应的值,也就是具体时间
String str=preciseShardingValue.getValue();
if (str.isEmpty()) {
throw new UnsupportedOperationException("分库字段为空");
}
//得到具体年,截取字符串要头不要尾
String value= StringUtils.substring(str,0,4);
for (String each:collection) {
if(each.endsWith(value)){
return each;
}
}
return null;
}
}
PreciseModuloTableShardingAlgorithm.java
package com.zym.config;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
public class PreciseModuloTableShardingAlgorithm implements PreciseShardingAlgorithm<String> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
//配置的分片的sharding-column对应的值
String timeValue = preciseShardingValue.getValue();
//判断timeValue是否为空
if(StringUtils.isBlank(timeValue)){
throw new UnsupportedOperationException("分表字段为空");
}
for (String each:collection) {
//得到具体月,截取字符串要头不要尾
String mouthValue= StringUtils.substring(timeValue,5,7);
int mouth = Integer.parseInt(mouthValue);
String suffix = null;
if (mouth >= 1 && mouth <= 3){
suffix = "1";
}else if (mouth >= 4 && mouth <= 6){
suffix = "2";
}else if (mouth >= 7 && mouth <= 9){
suffix = "3";
}else if (mouth >= 10 && mouth <= 12){
suffix = "4";
}
//循环每个库,看哪个库与当前条件匹配
if(each.endsWith(suffix)){
return each;
}
}
return null;
}
}
这样就实现了精确分片(按照时间分片)~