分库分表的 5种分片策略
本文是《ShardingSphere5.x分库分表原理与实战》系列的第五篇文章,我们一起梳理下ShardingSphere
框架中的核心部分分片策略和分片算法,其内部针为我们提供了多种分片策略和分片算法,来应对不同的业务场景,本着拿来即用的原则。
这次将详细介绍如何在ShardingSphere-jdbc
中实战 5 种分片策略和 12 种分片算法,自定义分片算法,比较它们的应用场景以及优劣。
分片策略
分片策略是分片键
和分片算法
的组合策略,真正用于实现数据分片操作的是分片键与相应的分片算法。在分片策略中,分片键确定了数据的拆分依据,分片算法则决定了如何对分片键值运算,将数据路由到哪个物理分片中。
由于分片算法的独立性,使得分片策略具有更大的灵活性和可扩展性。这意味着可以根据具体需求选择不同的分片算法,或者开发自定义的分片算法,以适应各种不同的分片场景。在分表和分库时使用分片策略和分片算法的方式是一致的。
注意:如果在某种分片策略中使用了不受支持的SQL操作符,比如 MYSQL 某些函数等,那么系统将无视分片策略,进行全库表路由操作。这个在使用时要慎重!
ShardingSphere
对外提供了standard
、complex
、hint
、inline
、none
5种分片策略。不同的分片策略可以搭配使用不同的分片算法,这样可以灵活的应对复杂业务场景。
标准分片策略
标准分片策略(standard
)适用于具有单一分片键的标准分片场景。该策略支持精确分片,即在SQL中包含=
、in
操作符,以及范围分片,包括BETWEEN AND
、>
、<
、>=
、<=
等范围操作符。
该策略下有两个属性,分片字段shardingColumn
和分片算法名shardingAlgorithmName
。
spring:
shardingsphere:
rules:
sharding:
tables:
t_order: # 逻辑表名称
# 数据节点:数据库.分片表
actual-data-nodes: db$->{0..1}.t_order_${1..10}
# 分库策略
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: order_id # 分片列名称
shardingAlgorithmName: # 分片算法名称
tableStrategy: # 分表策略,同分库策略
行表达式分片策略
行表达式分片策略(inline
)适用于具有单一分片键的简单分片场景,支持SQL语句中=
和in
操作符。
它的配置相当简洁,该分片策略支持在配置属性algorithm-expression
中书写Groovy
表达式,用来定义对分片健的运算逻辑,无需单独定义分片算法了。
spring:
shardingsphere:
rules:
sharding:
tables:
t_order: # 逻辑表名称
# 数据节点:数据库.分片表
actual-data-nodes: db$->{0..1}.t_order_${1..10}
# 分库策略
databaseStrategy: # 分库策略
inline: # 行表达式类型分片策略
algorithm-expression: db$->{order_id % 2} Groovy表达式
tableStrategy: # 分表策略,同分库策略
复合分片策略
复合分片策略(complex
)适用于多个分片键的复杂分片场景,属性shardingColumns
中多个分片健以逗号分隔。支持 SQL 语句中有>
、>=
、<=
、<
、=
、IN
和 BETWEEN AND
等操作符。
比如:我们希望通过user_id
和order_id
等多个字段共同运算得出数据路由到具体哪个分片中,就可以应用该策略。
spring:
shardingsphere:
rules:
sharding:
tables:
t_order: # 逻辑表名称
# 数据节点:数据库.分片表
actual-data-nodes: db$->{0..1}.t_order_${1..10}
# 分库策略
databaseStrategy: # 分库策略
complex: # 用于多分片键的复合分片场景
shardingColumns: order_id,user_id # 分片列名称,多个列以逗号分隔
shardingAlgorithmName: # 分片算法名称
tableStrategy: # 分表策略,同分库策略
Hint分片策略
Hint强制分片策略相比于其他几种分片策略稍有不同,该策略无需配置分片健,由外部指定分库和分表的信息,可以让SQL在指定的分库、分表中执行。
使用场景:
- 分片字段不存在SQL和数据库表结构中,而存在于外部业务逻辑。
- 强制在指定数据库进行某些数据操作。
比如,我们希望用user_id
做分片健进行路由订单数据,但是t_order
表中也没user_id
这个字段啊,这时可以通过Hint API
手动指定分片库、表等信息,强制让数据插入指定的位置。
spring:
shardingsphere:
rules:
sharding:
tables:
t_order: # 逻辑表名称
# 数据节点:数据库.分片表
actual-data-nodes: db$->{0..1}.t_order_${1..10}
# 分库策略
databaseStrategy: # 分库策略
hint: # Hint 分片策略
shardingAlgorithmName: # 分片算法名称
tableStrategy: # 分表策略,同分库策略
不分片策略
不分片策略比较好理解,设置了不分片策略,那么对逻辑表的所有操作将会执行全库表路由。
spring:
shardingsphere:
rules:
sharding:
tables:
t_order: # 逻辑表名称
# 数据节点:数据库.分片表
actual-data-nodes: db$->{0..1}.t_order_${1..10}
# 分库策略
databaseStrategy: # 分库策略
none: # 不分片
tableStrategy: # 分表策略,同分库策略