暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【手写数据库核心揭秘系列】查询执行器,表数据查询展示

开源无限 2025-04-16
52

💻 深耕数据库内核架构设计与开发十余年,曾主导多款高性能分布式数据库内核研发,攻克高并发、低延迟等核心技术难题。现倾力打造《从零手写数据库》系列教程,首次系统性公开数据库内核源码级实现细节!

🚀 从存储引擎、查询优化到分布式事务,手把手拆解核心模块;从语法解析树构建到执行计划生成,逐行代码还原设计精髓
🌟 无论你是数据库开发者、系统架构师,还是对底层技术充满好奇的极客,这里都有你想要的“硬核干货”!点击关注,与行业老兵共同探索数据库技术的星辰大海!

一、概述 

经过第一阶段对执行计划和执行器的开发,支持单表的查询和多表不带条件的联接查询。

现在创建的数据表对应在的数据字典都可以持久化保存,不再像之前,每次测试都需要先准备数据,可以将它们存储到单独的目录,在以后运行数据库时,指定对应的数据目录即可,就可以使用之前创建的数据表和表中的数据。

「准备数据」

创建两张数据表,分别是student表和teacher表。

[senllang@hatch exam_48]$ ./sqlparser 
create table student(sid integer,sname varchar,ssex char,sage integer,saddr varchar);
excutor CreateStmt success

create table teacher(tid integer,tname varchar,ssex char, tage integer);
excutor CreateStmt success

在两张表中插入数据,这里采用批量插入数据的方法。在student表中一次性插入两条,在teacher表中一次性插入三条数据。

insert into student values(1,'lilei','f',20,'beijing'),(2,'zhangwei','m',19,'hainan');
excutor InsertStmt success
insert into teacher values(1,'zhanghong','f',44),(2,'chenmei','m',32),(3,'zhaokuo','m',51);
excutor InsertStmt success

退出数据库软件,后台会保证所有数据都会持久化到磁盘中。

quit

二、全表查询 


本阶段完成了逻辑与物理执行计划的生成,使用迭代模型的执行器,并且表的定义信息在重启数据库后还能继续存在,让我们来看一下效果吧。

重启动动数据库,来查询一下之前定义的数据表。

查询student表的所有内容,这里没有指定目标列名称,会显示数据源表的所有列。

[senllang@hatch exam_48]$ ./sqlparser 
select * from student;
|sid     |sname        |ssex |sage    |saddr       |
|1       |lilei        |f    |20      |beijing     |
|2       |zhangwei     |m    |19      |hainan      |
excutor return 2 rows

三、别名查询 


给目标列指定了别名,结果显示时,标题使用别名作为列名称。只指定了两个目标列,所以最后的查询结果会经过投影运算,只显示两列的内容。

select sid as sno,sname as name from student ;
|sno |name  |
|1   |lilei |
|2   |zhangwei|
excutor return 2 rows

四、多表内联接查询 


在from子句中列出多个表时,它们之间通过内联接的方式进行运算,因为没有联接条件,所以是两个集合的积运算,最终结果的行数就是两表的行数积。在SQL中目标列和数据源表都指定了别名,所以结果中以别名来显示。

select s.sid as sno, t.tid as tno from student as s, teacher t;
|sno |tno |
|1   |1   |
|1   |2   |
|1   |3   |
|2   |1   |
|2   |2   |
|2   |3   |
excutor return 6 rows

 五、总结 


经过本阶段,可以查看表的内容,功能方面增加了逻辑执行计划,物理执行计划,以及基于迭代拉取模型的执行器,虽然现在只是一个基本的框架,它们内部进行过多的对执行计划进行优化,但是它们为以后功能扩展留下来伏笔。

在逻辑执行计划阶段,主要是运用关系代数进行优化,这需要分析各子句内部的关联性和子句之间的关联性,应用分配律,结合律等找到常量,或者下推一些条件到基础表扫描上;

在物理执行计划阶段,主要是找到最优的执行方法,每种运算可能会存在多种实现方法,基于统计信息来估算每种方法的代价,如果以代价作为权得,找到整个计划树权重最小的组合;

在执行器框架,已经不再是与某种执行树强关联,执行计划的节点可以任意变化,这使得我们可以添加更多的操作类型,比如常见的索引操作等等。

期待后续更多精彩内容吧。

🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀


【往期精彩推荐】

【手写数据库核心揭秘系列】别名查询,相同数据表却成为不同的数据源表

【手写数据库内核miniToadb】第81讲 数据字典的持久化存储

【手写数据库核心揭秘系列】第80讲 执行器基本操作符(扫描/投影/嵌套联接/选择)算法


文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论