一、介绍
1 根据解析上下文匹配数据库和表的分片策略,并生成路由路径。对于携带分片键的 SQL,根据分片键的 不同可以划分为单片路由 (分片键的操作符是等号)、多片路由 (分片键的操作符是 IN) 和范围路由 (分片 键的操作符是 BETWEEN)。不携带分片键的 SQL 则采用广播路由。
2 分片策略通常可以采用由数据库内置或由用户方配置。数据库内置的方案较为简单,内置的分片策略大 致可分为尾数取模、哈希、范围、标签、时间等。由用户方配置的分片策略则更加灵活,可以根据使用方 需求定制复合分片策略。如果配合数据自动迁移来使用,可以做到无需用户关注分片策略,自动由数据 库中间层分片和平衡数据即可,进而做到使分布式数据库具有的弹性伸缩的能力。
二、分片路由
用于根据分片键进行路由的场景,又细分为直接路由、标准路由和笛卡尔积路由这 3 种类型。y
三、直接路由
满足直接路由的条件相对苛刻,它需要通过 Hint(使用 HintAPI 直接指定路由至库表)方式分片,并且 是只分库不分表的前提下,则可以避免 SQL 解析和之后的结果归并。因此它的兼容性最好,可以执行包 括子查询、自定义函数等复杂情况的任意 SQL。直接路由还可以用于分片键不在 SQL 中的场景。
四、标准路由
1 标准路由是 ShardingSphere 最为推荐使用的分片方式,它的适用范围是不包含关联查询或仅包含绑定表 之间关联查询的 SQL。当分片运算符是等于号时,路由结果将落入单库(表),当分片运算符是 BETWEEN 或 IN 时,则路由结果不一定落入唯一的库(表),因此一条逻辑 SQL 最终可能被拆分为多条用于执行的 真实 SQL。
例子: 按照 order_id 的奇数和偶数进行数据分片去查询
SELECT * FROM t_order WHERE order_id IN (1, 2);
路由结果
SELECT * FROM t_order_0 WHERE order_id IN (1, 2);SELECT * FROM t_order_1 WHERE order_id IN (1, 2);
2 绑定表的关联查询与单表查询 (复杂度和性能相当)
例子: 包含绑定表的关联查询
SELECT * FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE order_id IN (1, 2);
路由
SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);
五、笛卡尔路由
笛卡尔路由是最复杂的情况,它无法根据绑定表的关系定位分片规则,因此非绑定表之间的关联查询需 要拆解为笛卡尔积组合执行。
SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHEREorder_id IN (1, 2);
六、广播路由
1 对于不携带分片键的 SQL,则采取广播路由的方式。
2 根据 SQL 类型又可以划分为全库表路由、全库路由、 全实例路由、单播路由和阻断路由这 5 种类型。
1 全库表路由
全库表路由用于处理对数据库中与其逻辑表相关的所有真实表的操作,主要包括不带分片键的 DQL 和 DML,以及 DDL 等。
SELECT * FROM t_order WHERE good_prority IN (1, 10);
路由
SELECT * FROM t_order_0 WHERE good_prority IN (1, 10);SELECT * FROM t_order_1 WHERE good_prority IN (1, 10);SELECT * FROM t_order_2 WHERE good_prority IN (1, 10);SELECT * FROM t_order_3 WHERE good_prority IN (1, 10);
2 全库路由
全库路由用于处理对数据库的操作,包括用于库设置的 SET 类型的数据库管理命令,以及 TCL 这样的事 务控制语句。在这种情况下,会根据逻辑库的名字遍历所有符合名字匹配的真实库,并在真实库中执行 该命令。
SET autocommit=0;
在 t_order 中执行,t_order 有 2 个真实库。则实际会在 t_order_0 和 t_order_1 上都执行这个命 令。
3 全实例路由
全实例路由用于 DCL 操作,授权语句针对的是数据库的实例。无论一个实例中包含多少个 Schema,每 个数据库的实例只执行一次。
CREATE USER customer@127.0.0.1 identified BY '123';
命令将在所有的真实数据库实例中执行,以确保 customer 用户可以访问每一个实例。
4 单播路由
单播路由用于获取某一真实表信息的场景,它仅需要从任意库中的任意真实表中获取数据即可。
DESCRIBE t_order;
t_order 的两个真实表 t_order_0,t_order_1 的描述结构相同,所以这个命令在任意真实表上选择执行一 次。
5 阻断路由
1 阻断路由用于屏蔽 SQL 对数据库的操作
USE order_db;
这个命令不会在真实数据库中执行,因为 ShardingSphere 采用的是逻辑 Schema 的方式,无需将切换数 据库 Schema 的命令发送至数据库中。
七、流程图

