TrivialDB - 一个简单的SQL引擎

栏目: 数据库 · 发布时间: 5年前

内容简介:TrivialDB是一个简单的数据库管理系统,我们实现了大部分常见的SQL语句和类型。同时支持多表连接、复杂表达式运算、多主键约束、外键约束、CHECK约束、UNIQUE和DEFAULT约束、聚集查询、利用B+树索引的查询优化,同时,我们支持任意长度的VARCHAR类型。项目地址是Contents

TrivialDB是一个简单的数据库管理系统,我们实现了大部分常见的 SQL 语句和类型。同时支持多表连接、复杂表达式运算、多主键约束、外键约束、CHECK约束、UNIQUE和DEFAULT约束、聚集查询、利用B+树索引的查询优化,同时,我们支持任意长度的VARCHAR类型。

项目地址是 https://github.com/miskcoo/TrivialDB ,这是这学期一门课程的大作业。

Contents

编译及运行

你需要有支持C++11特性的编译器,以及Bison和Flex两个库。本项目通过CMake来构建,在根目录运行

ccmake .

进行编译选项的设置,之后运行

cmake .
make -j8

进行项目的编译,编译后的可执行程序在 build/trivial_db 目录下。

编译后可以选择在 testcase 目录下运行 python3 run_test.py 运行测试程序。

系统功能

数据类型

数据库支持的基本类型有:

  • 整型(INT)
  • 浮点型(FLOAT)
  • 字符串型(VARCHAR)
  • 日期型(DATE),日期格式 YYYY-MM-dd

日期类型的字面值和字符串相同,在实现中如果必要可以转换为字符串。

SQL语句

我们支持的SQL语句一共有如下几种

  • 插入语句: INSERT INTO ... VALUES ...
  • 删除语句: DELETE FROM ... WHERE ...
  • 查询语句: SELECT ... FROM ... WHERE ...
  • 更新语句: UPDATE ... SET ... WHERE ...
  • 创建数据库: CREATE DATABASE ...
  • 删除数据库: DROP DATABASE ...
  • 切换数据库: USE ...
  • 显示数据库信息: SHOW DATABASE ...
  • 创建表: CREATE TABLE ...
  • 删除表: DROP TABLE ...
  • 显示表信息: SHOW TABLE ...
  • 创建索引: CREATE INDEX ...
  • 删除索引: DROP INDEX ...

复杂表达式处理

表达式大致可以分为两种:算术表达式和条件表达式。由于采用Bison进行解析,可以支持任意深度嵌套的复杂表达式。我们所支持的基本运算主要如下

  • 四则运算,针对整数和浮点数进行。
  • 比较运算符,即<=, <, =, >, >=, <>。
  • 模糊匹配运算符,即LIKE,其实现采用C++11的正则表达式库。
  • 范围匹配运算符,即IN,可以在表的CHECK约束中以及WHERE子句中使用。
  • 空值判定运算符,即IS NULL和IS NOT NULL两种。
  • 逻辑运算,包含NOT、AND和OR三种。

以下是一些复杂表达式运算的例子

UPDATE customer SET age = age + 1 WHERE age < 18 AND gender = 'F';
SELECT * FROM customer WHERE name LIKE 'John %son';
SELECT * FROM students WHERE grades IN ('A', 'B', 'C');
SELECT * FROM students WHERE name IS NOT NULL;

聚集查询

我们实现了五种聚集查询函数COUNT、SUM、AVG、MIN和MAX。其中COUNT不支持DISTINCT关键字。例如

SELECT COUNT(*) FROM customer WHERE age > 18;
SELECT AVG(age) FROM customer WHERE age <= 18;

属性完整性约束

我们支持多种属性完整性约束,分别是

  • 主键约束。一个表可以有多个列联合起来作为主键,只有在所有主键都相同时才认为两条记录有冲突,即这种情况下主键是一个元组。
  • 外键约束,每个域都可以有外键约束,引用另外一个表的主键。
  • UNIQUE约束,该约束限制某一列的值不能重复。
  • NOT NULL约束,该约束限制某一列不能有空值。
  • DEFAULT约束,该约束可以在INSERT语句不指定值是给某列赋予一个默认值。
  • CHECK约束,该约束可以对表中元素的值添加条件表达式的检查。

下面是一个简单的例子,注意如果在多个列都指定了PRIMARY KEY,那么就认为主键是一个元组,而不是有多个主键。例如Infos表的主键为(PersonID, InfoID)。

CREATE TABLE Persons (
    PersonID int PRIMARY KEY NOT NULL,
    Name varchar(20),
    Age int DEFAULT 1,
    Gender varchar(1),
    CHECK (Age >= 1 AND Age <= 100),
    CHECK (Gender IN ('F', 'M'))
);
 
CREATE TABLE Infos (
    PersonID int PRIMARY KEY,
    InfoID int PRIMARY KEY,
    FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);

多表连接查询

在SELECT语句中,我们支持任意多表的连接操作,例如

SELECT * FROM A, B, C WHERE A.ID = B.ID AND C.Name = A.Name

并且,对于多个表的连接中形如A.Col1 = B.Col2的条件,那么如果这两个列的某一个拥有索引,会利用索引进行查询优化。例如如下查询就可以优化

SELECT * FROM Persons, Infos WHERE Persons.PersonID = Infos.PersonID;
SELECT * FROM Persons, Infos, Datas WHERE Persons.PersonID = Infos.PersonID AND Datas.N IS NOT NULL;
SELECT * FROM Persons, Infos, Datas WHERE Persons.PersonID = Infos.PersonID AND Datas.ID = Infos.PersonID;

具体的优化方法以及何种查询可以优化见文档中"查询优化"部分。

表别名

我们在多表连接查询时支持通过别名(alias)的方式对一个表进行连接,例如

SELECT * FROM Persons AS P1, Persons AS P2 WHERE P1.PersonID = P2.PersonID;

以上所述就是小编给大家介绍的《TrivialDB - 一个简单的SQL引擎》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Wireshark网络分析实战

Wireshark网络分析实战

[以色列 Yoram Orzach / 古宏霞、孙余强 / 人民邮电出版社 / 2015-1 / 79.00元

本书采用步骤式为读者讲解了一些使用Wireshark来解决网络实际问题的技巧。 本书共分为14章,其内容涵盖了Wireshark的基础知识,抓包过滤器的用法,显示过滤器的用法,基本/高级信息统计工具的用法,Expert Info工具的用法,Wiresahrk在Ethernet、LAN及无线LAN中的用法,ARP和IP故障分析,TCP/UDP故障分析,HTTP和DNS故障分析,企业网应用程序行......一起来看看 《Wireshark网络分析实战》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具