核心概念

真实表(Physical Table)

真实表是指实际存在于数据库中的物理表,是数据最终存储的实体表。在分库分表场景中,这些表通常带有数字后缀来表示分片。例如:

  • b_order0:表示订单表的第一个分片
  • b_order1:表示订单表的第二个分片
  • b_order_item0:表示订单明细表的第一个分片

这些真实表分散在不同的数据库实例或数据源中,每个表存储部分数据。

逻辑表(Logical Table)

逻辑表是对同一类表结构的抽象表示,是应用程序中使用的表名。它代表了一组分片表的集合。例如:

  • b_order:表示所有订单分片表的逻辑名称
  • b_order_item:表示所有订单明细分片表的逻辑名称

在SQL查询中,开发者只需要使用逻辑表名,分片中间件会自动将查询路由到对应的真实表。

数据节点(Data Node)

数据节点是分片后的基本数据单元,由数据源和真实表组成,格式通常为数据源名.真实表名。例如:

  • ds0.b_order1:表示数据源ds0中的b_order1表
  • ds1.b_order_item2:表示数据源ds1中的b_order_item2表

绑定表(Binding Table)

绑定表是指分片规则完全一致的主表和子表关系。它们具有相同的分片键和分片算法,确保关联数据存储在同一分片上。

绑定表优势

  1. 关联查询时可直接在单个分片上完成,避免跨分片查询
  2. 消除笛卡尔积问题,提高查询效率
  3. 保证事务一致性,相关数据在同一分片

绑定表配置示例

spring:
  shardingsphere:
    sharding:
      binding-tables:
        - b_order,b_order_item
        - t_user,t_user_address

笛卡尔积问题

不配置绑定表时,采用笛卡尔积关系关联,会生成4个SQL:

SELECT * FROM b_order0 o
JOIN b_order_item0 i ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

SELECT * FROM b_order0 o
JOIN b_order_item1 i ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

SELECT * FROM b_order1 o
JOIN b_order_item0 i ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

SELECT * FROM b_order1 o
JOIN b_order_item1 i ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

配置绑定表后,生成2个SQL:

SELECT * FROM b_order0 o
JOIN b_order_item0 ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

SELECT * FROM b_order1 o
JOIN b_order_item1 ON(o.order_id=i.order_id)
WHERE o.order_id IN(10,11);

广播表

广播表是一种特殊的数据分片策略,主要用于处理那些不需要分片但又需要频繁关联查询的小型数据表。

特点

  1. 数据规模较小:数据量通常在几百条到几万条之间
  2. 高频率的关联查询需求:需要与海量数据进行JOIN操作
  3. 数据一致性要求高:内容相对静态,更新频率低

典型应用场景

  1. 基础数据表:国家/地区代码表、产品分类表
  2. 系统配置表:系统参数表、用户角色表
  3. 维度表:时间维度表、组织机构表

分片算法详解

1. 精确分片算法(PreciseShardingAlgorithm)

  • 适用场景:处理使用单一分片键的等值查询(IN操作符)场景
  • 典型查询示例WHERE user_id IN (1001, 1002, 1003)

2. 范围分片算法(RangeShardingAlgorithm)

  • 适用场景:处理使用单一分片键的范围查询场景
  • 支持操作符:BETWEEN AND、>、<、>=、<=

3. 复合分片算法(ComplexKeysShardingAlgorithm)

  • 适用场景:处理多分片键组合的复杂分片逻辑
  • 特点:支持多个分片键的组合条件

4. Hint分片算法(HintShardingAlgorithm)

  • 适用场景:分片字段不由SQL决定,而由外部条件指定的特殊场景
  • 实现方式
    • Java API方式
    • SQL注释方式
// Java API方式
HintManager.getInstance().addDatabaseShardingValue("logicTable", "shardingValue");
/* Sharding:table=employee_01 */ SELECT * FROM employee

分片策略详解

1. 标准分片策略(StandardShardingStrategy)

仅支持单个分片键,适用于大多数常规分片场景。需要配置PreciseShardingAlgorithm(必选)和RangeShardingAlgorithm(可选)。

2. 复合分片策略(ComplexShardingStrategy)

支持多个分片键组合,适合复杂业务场景。

3. 行表达式分片策略(InlineShardingStrategy)

基于Groovy表达式的轻量级分片方案,无需编写Java代码。

# 按用户ID取模分8张表
t_user_$->{u_id % 8}

4. Hint分片策略(HintShardingStrategy)

通过编程方式指定分片值,完全绕过SQL解析过程。

5. 不分片策略(NoneShardingStrategy)

显式声明不分片,适合小表不需要分片的场景。

策略配置

数据源分片策略

主要用于定义数据记录如何被分配到不同的物理数据源节点上。

表分片策略

负责定义数据记录在目标数据源内部的表级分布规则,必须基于数据源分片策略的结果。