Sharding-JDBC笔记02-Sharding-JDBC执行原理

news/2025/3/17 16:55:07/文章来源:https://www.cnblogs.com/jock766/p/18503570

一、基本概念

在了解Sharding-JDBC的执行原理前,需要了解以下概念:


逻辑表

水平拆分的数据表的总称。例:订单数据表根据主键尾数拆分为10张表,分别是 t_order_0 、 t_order_1 到t_order_9 ,他们的逻辑表名为 t_order


逻辑表

在分片的数据库中真实存在的物理表。即上个示例中的 t_order_0 到 t_order_9


数据节点

数据分片的最小物理单元。由数据源名称和数据表组成,例: ds_0.t_order_0


绑定表指分片规则一致的主表和子表。例如: t_order 表和 t_order_item 表,均按照 order_id 分片,绑定表之间的分区键完全相同,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。举例说明,如果SQL为:

在不配置绑定表关系时,假设分片键 order_id 将数值10路由至第0片,将数值11路由至第1片,那么路由后的SQL应该为4条,它们呈现为笛卡尔积:

在配置绑定表关系后,路由的SQL应该为2条:


广播表

指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。


分片键

用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL中如果无分片字段,将执行全路由,性能较差。

除了对单分片字段的支持,Sharding-Jdbc也支持根据多个字段进行分片。


分片算法

通过分片算法将数据分片,支持通过 = 、 BETWEEN 和 IN 分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高。包括:精确分片算法 、范围分片算法 ,复合分片算法 等。

例如:

  • where order_id = ? 将采用精确分片算法,

  • where order_id in (?,?,?)将采用精确分片算法,

  • where order_id BETWEEN ? and ? 将采用范围分片算法,


分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。内置的分片策略大致可分为尾数取模、哈希、范围、标签、时间等。

由用户方配置的分片策略则更加灵活,常用的使用行表达式配置分片策略,它采用Groovy表达式表示,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为 t_user_0 到 t_user_7


自增主键生成策略

通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复


二、SQL解析

当Sharding-JDBC接受到一条SQL语句时,会陆续执行 SQL解析 => 查询优化 => SQL路由 => SQL改写 => SQL执行 =>结果归并 ,最终返回执行结果。

SQL解析过程分为词法解析和语法解析。 词法解析器用于将SQL拆解为不可再分的原子符号,称为Token。并根据不同数据库方言所提供的字典,将其归类为关键字,表达式,字面量和操作符。

再使用语法解析器将SQL转换为抽象语法树。例如,以下SQL:


三、SQL路由

SQL路由就是把针对逻辑表的数据操作映射到对数据结点操作的过程。根据解析上下文匹配数据库和表的分片策略,并生成路由路径。 对于携带分片键的SQL,根据分片键操作符不同可以划分为单片路由(分片键的操作符是等号)、

多片路由(分片键的操作符是IN)和范围路由(分片键的操作符是BETWEEN),不携带分片键的SQL则采用广播路由。根据分片键进行路由的场景可分为直接路由、标准路由、笛卡尔路由等。


标准路由

标准路由是Sharding-Jdbc最为推荐使用的分片方式,它的适用范围是不包含关联查询或仅包含绑定表之间关联查询的SQL。 当分片运算符是等于号时,路由结果将落入单库(表),当分片运算符是BETWEEN或IN时,则路由结果不一定落入唯一的库(表),

因此一条逻辑SQL最终可能被拆分为多条用于执行的真实SQL。 举例说明,如果按照 order_id 的奇数和偶数进行数据分片,一个单表查询的SQL如下:

那么路由的结果应为:

绑定表的关联查询与单表查询复杂度和性能相当。举例说明,如果一个包含绑定表的关联查询的SQL如下:

那么路由的结果应为:

可以看到,SQL拆分的数目与单表是一致的。


笛卡尔路由

笛卡尔路由是最复杂的情况,它无法根据绑定表的关系定位分片规则,因此非绑定表之间的关联查询需要拆解为笛卡尔积组合执行。 如果上个示例中的SQL并未配置绑定表关系,那么路由的结果应为:

笛卡尔路由查询性能较低,需谨慎使用。


全库表路由

对于不携带分片键的SQL,则采取广播路由的方式。根据SQL类型又可以划分为全库表路由、全库路由、全实例路由、单播路由和阻断路由这5种类型。其中全库表路由用于处理对数据库中与其逻辑表相关的所有真实表的操作,主要包括不带分片键的DQL(数据查询)和DML(数据操纵),以及DDL(数据定义)等。例如:

则会遍历所有数据库中的所有表,逐一匹配逻辑表和真实表名,能够匹配得上则执行。路由后成为


四、SQL改写

工程师面向逻辑表书写的SQL,并不能够直接在真实的数据库中执行,SQL改写用于将逻辑SQL改写为在真实数据库中可以正确执行的SQL

如一个简单的例子,若逻辑SQL为:

假设该SQL配置分片键order_id,并且order_id=1的情况,将路由至分片表1。那么改写之后的SQL应该为:

再比如,Sharding-JDBC需要在结果归并时获取相应数据,但该数据并未能通过查询的SQL返回。 这种情况主要是针对GROUP BY和ORDER BY。结果归并时,需要根据 GROUP BY 和 ORDER BY 的字段项进行分组和排序,但如果原始SQL的选择项中若并未包含分组项或排序项,则需要对原始SQL进行改写。

先看一下原始SQL中带有结果归并所需信息的场景:

由于使用user_id进行排序,在结果归并中需要能够获取到user_id的数据,而上面的SQL是能够获取到user_id数据的,因此无需补列。如果选择项中不包含结果归并时所需的列,则需要进行补列,如以下SQL:


五、SQL执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/822016.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C中的open(), write(), close(), fopen()

open() 函数原型#include <fcntl.h> #include <unistd.h>int open(const char *pathname, int flags, mode_t mode);pathname:要打开的文件的路径。flags:打开文件的模式(如只读、只写等)。常用的标志包括:O_RDONLY:只读模式。 O_WRONLY:只写模式。 O_RDWR:…

C#数据结构与算法4-C# 简单排序方法

一 排序 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题。例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难。同样,存储在计算机中的数据的次序,对于处理这些数据的算法的速度和简便性而言,也具有非常深远的意义。 二 基本概念…

C#数据结构与算法5-C# 快速排序

一 快速排序 快速排序由于排序效率综合来说你几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影…

C#数据结构与算法4-C# 快速排序

一 快速排序 快速排序由于排序效率综合来说你几种排序方法中效率较高,因此经常被采用,再加上快速排序思想----分治法也确实实用,因此很多软件公司的笔试面试,包括像腾讯,微软等知名IT公司都喜欢考这个,还有大大小的程序方面的考试如软考,考研中也常常出现快速排序的身影…

C#数据结构与算法1-C# 线性表

一 什么是线性表 线性表是最简单、最基本、最常用的数据结构。线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系。这种一对一的关系指的是数据元素之间的位置关系,即:( 1)除第一个位置的数据元素外,其它数据元素位置的前面都…

C#数据结构与算法2-C# 栈和队列

一 栈和队列 栈和队列是非常重要的两种数据结构,在软件设计中应用很多。栈和队列也是线性结构,线性表、栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制。栈的操作只能在表的一端进行,队列的插入…

C# 托盘通知

一 托盘通知 NotifyIcon托盘通知:程序可以在通知区创建一个通知图标。一般地,可以提示一个气泡通知,右键菜单支持。准备:需要一个图标(*.ico),用于显示在通知区。如果没有ico格式,可以将png图片转成ico。 演示:在项目中添加托盘通知。① 设置文本Text;② 选择图标Icon; …

学习强化学习有哪些工具

强化学习是一种动态的学习方法,目前有许多工具可以帮助研究者和开发者入门和深入学习。主要工具包括:1、OpenAI Gym:一个用于开发和比较强化学习算法的工具包;2、TensorFlow Agents:一个基于TensorFlow的强化学习库;3、Stable Baselines:一个高质量的强化学习库。其中,…

在C语言中如何处理大型项目的模块化

### 在C语言中如何处理大型项目的模块化 在处理大型项目的模块化时,C语言中的关键策略包括使用函数库、分离编译、使用条件编译指令、以及采用模块化设计原则。其中,使用函数库是最直接有效的方法之一,允许开发者重用代码、减少重复工作,并保持代码的整洁和可管理性。 详细…

基类指针、虚纯虚函数、多态性、虚析构

多态 基类指针 // 父类指针可以 new 一个子类对象 Human *pman = new Man(); Human *pwman = new Wonan();抛出问题:父类指针没有办法调用子类的成员函数,那么你为什么还让父类指针 new 一个子类对象呢? 下面与虚函数搭配 虚函数(动态绑定) 我们只定义一个对象指针,就能…

SATA和NVMe SSD在速度上有多大差异

SATA和NVMe SSD在速度上的差异主要体现在:一、传输接口和带宽能力差异;二、读写速度的差异;三、应用场景和效率的差异;四、价格和市场趋势的差异;五、未来发展的差异。实际上,NVMe SSD在速度上远超SATA SSD,特别适合需要高速数据处理的应用场景,如高端游戏、视频编辑和…