分片策略
基本概念
分片键
用于分片的字段,是将数据库或表拆分的字段,比如,我可以使用user_id作为分片键将用户数据分到不同的表中,这里的user_id就是分片键,除了这种单字段分片,ShardingSphere还支持多个分片字段。SQL中如果没有分片字段,将执行全路由,也就是会把SQL发送到所有的数据分片上执行,性能较差。
分片算法
分片算法描述的是如何进行分片,需要结合分片键使用。比如我需要使用user_id对2取模进行分表,那么这里取模就是分片算法,SQL特殊查询如>、<、=、IN和Between会出现问题。
问题,如SQL
select * from t_order
有2个库2个表
db1 -> t_order_1 , t_order_2
db2 -> t_order_1 , t_order_2
以取摸%2算法计算,偶数id分配在表2,库2,,奇数同理,查询=>8888,10000
由于没有重写路由算法,SQL会以全库全表形式查询,实际查询查询了4个数据库。
分片策略
分片策略是一种抽象的概念,实际分片操作的是由分片算法和分片健来完成的。
真正可⽤于分⽚操作的是分⽚键 + 分⽚算法,也就是分⽚策略。
分片算法
sharding-jdbc 提供了多种分片算法:
提供了抽象分片算法类:ShardingAlgorithm,根据类型又分为:精确分片算法、区间分片算法、复合分片算法以及Hint分片算法;
- 精确分片算法:对应PreciseShardingAlgorithm类,主要用于处理 = 和 IN的分片;
- 区间分片算法:对应RangeShardingAlgorithm类,主要用于处理 BETWEEN AND, >, <, >=, <= 分片;
- 复合分片算法:对应ComplexKeysShardingAlgorithm类,用于处理使用多键作为分片键进行分片的场景;
- Hint分片算法:对应HintShardingAlgorithm类,用于处理使用 Hint 行分片的场景;
1、精确分片算法 PreciseShardingAlgorithm
用于单个字段作为分片键,SQL中有 = 与 IN 等条件的分片,需要配合 StandardShardingStrategy 使⽤。
2、范围分片算法 RangeShardingAlgorithm
范围分片算法(RangeShardingAlgorithm)用于单个字段作为分片键,SQL中有 BETWEEN AND、>、<、>=、<= 等条件的分片,需要需要配合 StandardShardingStrategy 使⽤。/3、复合分片算法 ComplexKeysShardingAlgorithm
对应 ComplexKeysShardingAlgorithm,⽤于处理使⽤ 多键作为分⽚键 进⾏分⽚的场景,
(多个字段作为分片键),同时获取到多个分片健的值,根据多个字段处理业务逻辑。
包含多个分⽚键的逻辑较复杂,需要应⽤开发者⾃⾏处理其中的复杂度。
需要配合 ComplexShardingStrategy 使⽤。
需要在复合分片策略(ComplexShardingStrategy )下使用。
Hint 分片算法 HintShardingAlgorithm
Hint 分片算法(HintShardingAlgorithm)稍有不同
前面的算法(如StandardShardingAlgorithm)都是解析 SQL 语句, 提取分片值,并根据设置的分片算法进行分片。
4、Hint 分片算法 指定分⽚值而⾮从 SQL 中提取,而是手工设置的⽅式,进⾏分⽚的策略。
对于分⽚值⾮ SQL 决定,不是来自于分片建,甚至连分片建都没有 ,而由其他外置条件决定的场景,可使⽤Hint 分片算法 。
就需要通过 Java API 等方式 指定 分片值,这也叫强制路由、或者说 暗示路由。
例: 内部系统,按照员⼯登录主键分库,而数据库中并⽆此字段。
SQL Hint ⽀持通过 Java API 和 SQL 注释(待实现)两种⽅式使⽤。
标准分片策略
标准分片策略的使用场景:SQL 语句中有>,>=, <=,<,=,IN 和 BETWEEN AND 操作符,都可以应用此分片策略。
标准分片策略(StandardShardingStrategy),它只支持对单个分片健(字段)为依据的分库分表,
并提供了两种分片算法 PreciseShardingAlgorithm(精准分片)和 RangeShardingAlgorithm(范围分片)。
其中,精准分片算法是必须实现的算法,用于 SQL 含有 = 和 IN 的分片处理;
范围分片算法是非必选的,用于处理含有 BETWEEN AND 、>,>=, <=,<的分片处理。
RangeShardingAlgorithm 是可选的。
精准分片用于处理含有= 、in的分片处理。
范围分片 用于处理含有 BETWEEN AND
、>
,>=
, <=
,<
的分片处理。
**PreciseShardingAlgorithm**接口
处理 = 和 IN 查询:
其中Collection databaseNames 为分片库名称,PreciseShardingValue
为分片属性,其中 logicTableName
为逻辑表,columnName
分片健(字段),value
为从 SQL 中解析出的分片健的值。分表以上参数同理。
public class MyDBProcessShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
// databaseNames 重写分库规则
@Override
public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
for (String key : databaseNames) {
//TODO
}
}
// tableNames 重写分表规则
@Override
public String doSharding(Collection<String> tableNames,
PreciseShardingValue<Long> shardingValue) {
for (String key : tableNames) {
//TODO
}
}
**RangeShardingAlgorithm**接口
使用范围查询:
RangeShardingValue
这里取值方式稍有不同, lowerEndpoint
表示起始值, upperEndpoint
表示截止值。
public class MyDBRangeAlgorithm implements RangeShardingAlgorithm<Integer> {
@Override
public Collection<String> doSharding(Collection<String> databaseNames, RangeShardingValue<Integer> rangeShardingValue) {
HashMap<String> result = new HashMap<>();
int lower = rangeShardingValue.getValueRange().lowerEndpoint();
int upper = rangeShardingValue.getValueRange().upperEndpoint();
for (int i = ; i <= upper; i++) {
//TODO
}
return result;
}
}