跳至主要內容

分库分表的 5种分片策略

原创程序员小富大约 4 分钟

本文是《ShardingSphere5.x分库分表原理与实战》系列的第五篇文章,我们一起梳理下ShardingSphere框架中的核心部分分片策略分片算法,其内部针为我们提供了多种分片策略和分片算法,来应对不同的业务场景,本着拿来即用的原则。

这次将详细介绍如何在ShardingSphere-jdbc中实战 5 种分片策略和 12 种分片算法,自定义分片算法,比较它们的应用场景以及优劣。

20240414022108

分片策略

分片策略是分片键分片算法的组合策略,真正用于实现数据分片操作的是分片键与相应的分片算法。在分片策略中,分片键确定了数据的拆分依据,分片算法则决定了如何对分片键值运算,将数据路由到哪个物理分片中。

由于分片算法的独立性,使得分片策略具有更大的灵活性和可扩展性。这意味着可以根据具体需求选择不同的分片算法,或者开发自定义的分片算法,以适应各种不同的分片场景。在分表和分库时使用分片策略和分片算法的方式是一致的

注意:如果在某种分片策略中使用了不受支持的SQL操作符,比如 MYSQL 某些函数等,那么系统将无视分片策略,进行全库表路由操作。这个在使用时要慎重!

ShardingSphere对外提供了standardcomplexhintinlinenone5种分片策略。不同的分片策略可以搭配使用不同的分片算法,这样可以灵活的应对复杂业务场景。

标准分片策略

标准分片策略(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 语句中有>>=<=<=INBETWEEN AND 等操作符。

比如:我们希望通过user_idorder_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: # 分表策略,同分库策略

代码示例

Github

本文 Github 案例地址