TrivialDB是一个简单的数据库管理系统,实现了大部分常见的SQL语句和类型。同时支持多表连接、复杂表达式运算、多主键约束、外键约束、CHECK约束、UNIQUE和DEFAULT约束、聚集查询、利用B+树索引的查询优化,同时,支持任意长度的VARCHAR类型。
系统功能数据类型数据库支持的基本类型有:
整型(INT)浮点型(FLOAT)字符串型(VARCHAR)日期型(DATE),日期格式YYYY-MM-dd日期类型的字面值和字符串相同,在实现中如果必要可以转换为字符串。
SQL语句支持的SQL语句一共有如下几种
插入语句:INSERTINTO...VALUES...删除语句:DELETEFROM...WHERE...查询语句:SELECT...FROM...WHERE...更新语句:UPDATE...SET...WHERE...创建数据库:CREATEDATABASE...删除数据库:DROPDATABASE...切换数据库:USE...显示数据库信息:SHOWDATABASE...创建表:CREATETABLE...删除表:DROPTABLE...显示表信息:SHOWTABLE...创建索引:CREATEINDEX...删除索引:DROPINDEX...复杂表达式处理表达式大致可以分为两种:算术表达式和条件表达式。由于采用Bison进行解析,可以支持任意深度嵌套的复杂表达式。TrivialDB支持的基本运算主要如下
四则运算,针对整数和浮点数进行。比较运算符,即<=、<、=、>、>=与<>。模糊匹配运算符,即LIKE,其实现采用C++11的正则表达式库。范围匹配运算符,即IN,可以在表的CHECK约束中以及WHERE子句中使用。空值判定运算符,即ISNULL和ISNOTNULL两种。逻辑运算,包含NOT、AND和OR三种。以下是一些复杂表达式运算的例子
UPDATEcustomerSETage=age+1WHEREage<18ANDgender='F';SELECT*FROMcustomerWHEREnameLIKE'John%son';SELECT*FROMstudentsWHEREgradesIN('A','B','C');SELECT*FROMstudentsWHEREnameISNOTNULL;聚集查询实现了五种聚集查询函数COUNT、SUM、AVG、MIN和MAX。其中COUNT不支持DISTINCT关键字。例如
SELECTCOUNT(*)FROMcustomerWHEREage>18;SELECTAVG(age)FROMcustomerWHEREage<=18;属性完整性约束支持多种属性完整性约束,分别是
主键约束。一个表可以有多个列联合起来作为主键,只有在所有主键都相同时才认为两条记录有冲突,即这种情况下主键是一个元组。外键约束,每个域都可以有外键约束,引用另外一个表的主键。UNIQUE约束,该约束限制某一列的值不能重复。NOTNULL约束,该约束限制某一列不能有空值。DEFAULT约束,该约束可以在INSERT语句不指定值是给某列赋予一个默认值。CHECK约束,该约束可以对表中元素的值添加条件表达式的检查。下面是一个简单的例子,注意如果在多个列都指定了PRIMARYKEY,那么就认为主键是一个元组,而不是有多个主键。例如Infos表的主键为(PersonID,InfoID)。
CREATETABLEPersons(PersonIDintPRIMARYKEYNOTNULL,Namevarchar(20),AgeintDEFAULT1,Gendervarchar(1),CHECK(Age>=1ANDAge<=100),CHECK(GenderIN('F','M')));CREATETABLEInfos(PersonIDintPRIMARYKEY,InfoIDintPRIMARYKEY,FOREIGNKEY(PersonID)REFERENCESPersons(PersonID));多表连接查询在SELECT语句中,我们支持任意多表的连接操作,例如
SELECT*FROMA,B,CWHEREA.ID=B.IDANDC.Name=A.Name并且,对于多个表的连接中形如A.Col1=B.Col2的条件,那么如果这两个列的某一个拥有索引,会利用索引进行查询优化。例如如下查询就可以优化
SELECT*FROMPersons,InfosWHEREPersons.PersonID=Infos.PersonID;SELECT*FROMPersons,Infos,DatasWHEREPersons.PersonID=Infos.PersonIDANDDatas.NISNOTNULL;SELECT*FROMPersons,Infos,DatasWHEREPersons.PersonID=Infos.PersonIDANDDatas.ID=Infos.PersonID;具体的优化方法以及何种查询可以优化见文档中"查询优化"部分。
表别名我们在多表连接查询时支持通过别名(alias)的方式对一个表进行连接,例如
SELECT*FROMPersonsASP1,PersonsASP2WHEREP1.PersonID=P2.PersonID;
评论