在SQL中,数据定义语言(DDL)是一类用于创建与维护数据库对象(如数据库、数据库表、索引、视图、触发器、存储过程等)的SQL语句类型。DDL语句分为CREATE、ALTER与DROP这3类语句,它们分别完成数据库对象的创建、修改、删除等操作处理。学习者要掌握数据库对象的SQL编程(如创建、修改、删除等)操作处理,则需要理解各个DDL语句的使用。
在数据库系统中,最大的数据库对象就是数据库本身。SQL提供了数据库对象的创建与维护语句,包括数据库创建、数据库修改、数据库删除等。以下分别对这些语句进行说明:
基本语句格式为:
其中,CREATE DATABASE为创建数据库语句的关键词,<数据库名>为被创建数据库的标识符名称。
【例3-1】 在PostgreSQL DBMS中,创建一个名称为“hr”的人事管理数据库。可在PostgreSQL数据库管理器工具中,执行如下数据库创建SQL语句:
其数据库创建SQL语句与执行结果界面如图3-1所示。
上面执行的数据库创建SQL语句为基本格式语句,它是按DBMS默认设置参数来创建数据库hr的。若用户需要在数据库创建时自己定义参数,可使用完整格式的数据库创建SQL语句,其SQL格式如下:
图3-1 pgAdmin管理器中执行数据库创建SQL语句
当创建数据库的SQL语句中带有相应参数时,DBMS将按照该参数要求创建数据库。否则,DBMS将按照默认的模板数据库参数创建新数据库。
【例3-2】 在PostgreSQL DBMS中,创建一个图书借阅管理数据库BookDB。假定该数据库的用户名为BookApp,使用表空间BookTabSpace。其数据库创建SQL语句与执行结果界面如图3-2所示。
图3-2 使用带自定义参数的数据库创建SQL语句
使用ALTER DATABASE语句,可以修改数据库的属性。数据库修改语句包括更改数据库配置参数、数据库名称、数据库所有者、数据库默认表空间等。数据库修改SQL语句格式为:
主要的属性修改语句如下。
【例3-3】 将数据库demoDB换名为MyDemoDB,其SQL操作语句为:
基本语句格式为:
其中,DROP DATABASE为语句命令关键词,<数据库名>为服务器中已存在的数据库名称。此语句执行后,该数据库从数据库服务器中被删除。
【例3-4】 删除样本数据库demoDB,其操作语句为:
DROP DATABASE语句不能用在存储过程、触发器、事务处理程序中。
数据库表是数据库中最基本的数据存储对象。在SQL中,使用DDL语句可完成数据库表创建、表修改、表删除等操作。
基本语句格式为:
其中,CREATE TABLE为创建表语句的关键词,<表名>为将被创建的数据库表名称。一个数据库中不允许有同名的数据表。在一个表中,可以定义多个列,但不允许有两个属性列同名。针对表中每个属性列,都需要指定其取值的数据类型。在定义属性列时,有时还需要给出该列的完整性约束。
【例3-5】 在2.3节的选课管理系统数据库中,需要创建学生信息表(Student),其创建SQL语句如下:
在该表中,StudentID列作为主键,由列约束关键词PRIMARY KEY定义。StudentName列不允许空值,即必须有学生姓名数据。表中其他列可以为空值,由列约束关键词NULL定义。当列约束未给出时,默认该列允许空值。主键列默认必须有值,不允许为空。
在PostgreSQL数据库管理工具中,通过执行上述SQL语句,可以创建学生信息表,其运行结果界面如图3-3所示。
图3-3 执行学生信息表创建SQL语句及结果
(1)列约束关键词
上面执行的数据表创建SQL语句,使用了基本的列约束PRIMARY KEY、NOT NULL和NULL关键词。除了这些基本列约束外,还可根据实际应用需要,使用UNIQUE、CHECK、DEFAULT等关键词分别约束列取值的唯一性、值范围和默认值。以下实例将使用这些关键词定义课程信息表(Course)的列约束。
【例3-6】 在2.3节的选课管理系统数据库中,需要创建课程信息表(Course),其创建SQL语句如下:
在PostgreSQL数据库管理工具中,通过执行上述SQL语句,可以创建课程信息表,其运行结果界面如图3-4所示。
在创建课程信息表的过程中,使用关键词UNIQUE定义CourseName列取值唯一约束,使用CHECK关键词定义CourseType列取值范围为“基础课”“专业”“选修”,使用DEFAULT关键词定义TestMethod列的默认值为“闭卷考试”。
图3-4 执行课程信息表创建SQL语句及结果
(2)表约束关键词
在前面的数据库表创建语句中,使用列约束关键词PRIMARY KEY定义表的主键列。这种方式只能定义单个列作为主键,若要定义由多个列构成的复合主键,则需要使用表约束方式。这可以通过在创建表的SQL语句中,加入CONSTRAINT关键词来标识表约束,并定义复合主键。
【例3-7】 在2.3节的选课管理系统数据库中,需要创建开课计划表(Plan),其创建SQL语句如下:
在PostgreSQL数据库管理工具中,通过执行上述SQL语句,可以创建开课计划表,其运行结果界面如图3-5所示。
图3-5 执行开课计划表创建SQL语句及结果1
在使用表约束方式定义主键时,可以赋予约束名称,以便对约束进行标识。通常使用“_PK”作为主键约束名称后缀,如在本例中主键约束名称为CoursePlan_PK,该约束定义(CourseID,TeacherID)复合键作为Plan表的主键。
(3)表约束定义代理键
在数据库应用的一些情况下,使用代理键来替代复合主键,可以方便地对主键进行操作和提高处理性能。在PostgreSQL数据库管理工具中,可以使用表约束CONSTRAINT和自动递增序列数据类型Serial来定义代理键,同时自动在该表所在Schema中创建一个名为tableName_columnName_seq的序列,该序列为代理键提供值。不同DBMS定义代理键的方式有所不同,具体需参考该DBMS产品的技术文献。
【例3-8】 在创建开课计划表(Plan)时,若定义代理键CoursePlanID为主键,其创建SQL语句如下:
在PostgreSQL数据库管理工具中,通过执行上述SQL语句,可以创建开课计划表,其运行结果界面如图3-6所示。
图3-6 执行开课计划表创建SQL语句及结果2
在图3-6所示的开课计划表创建SQL语句中使用代理键CoursePlanID取代原复合键(CourseID,TeacherID)作为主键。其中,CoursePlanID列的数据类型设置为serial,同时系统自动生成plan_courseplanid_seq序列为代理键列CoursePlanID提供值。
(4)表约束定义外键
在SQL数据定义语句中,通过表约束CONSTRAINT关键词,不但可以定义表的主键,也可以定义表中的外键。在执行SQL表创建语句时,也可以建立该表与其关联表的参照完整性约束,即约束本表中的外键列取值参照关联表的主键列值。
【例3-9】 在2.3节的选课管理系统数据库中,创建选课注册表(Register),需要定义本表外键列,并参照其关联表的主键列,其创建SQL语句如下:
在PostgreSQL数据库管理工具中,通过执行上述SQL语句,可以创建选课注册表,其运行结果界面如图3-7所示。
图3-7 执行选课注册表创建SQL语句及结果
基本语句格式为:
其中,ALTER TABLE为数据库表修改语句的关键词,<表名>为将被修改的数据库表名称,<改变方式>用于指定对表结构的修改方式,主要有如下几种修改方式:
1)ADD修改方式。它用于增加新列或列完整性约束,其语法格式为:
2)DROP修改方式。它用于删除指定列或列的完整性约束条件,其语法格式为:
3)RENAME修改方式。它用于修改表名称、列名称,其语法格式为:
4)ALTER修改方式。它用于修改列的数据类型,其语法格式为:
【例3-10】 学生信息表(Student)的原始数据如图3-8所示。当该表中需要增加一个“Email”列时,可执行如下表修改SQL语句:
该SQL语句执行后,学生信息表的数据如图3-9所示。
图3-8 学生信息表原始数据
图3-9 学生信息表增添Email列后的数据
【例3-11】 在图3-9所示的学生信息表结构中。当需要删除表中的“StudentPhone”列时,可执行如下表修改SQL语句:
修改后的表数据如图3-10所示。
图3-10 学生信息表删除StudentPhone列后的数据
基本语句格式为:
其中,DROP TABLE为数据库表删除语句的关键词,<表名>为将被删除的数据库表名称。该语句执行后,会删除指定的数据表,包括表结构和表中数据。
需注意:DROP TABLE不能直接删除有FOREIGN KEY约束或引用的表。只有先删除FOREIGN KEY约束或引用的表后,才能删除本表。
在数据库中,通常一些表包含大量数据,例如一个表中有上百万行记录数据。若要对这些表进行数据查询,最基本的搜索信息方式是全表搜索,即将所有行数据一一取出,与查询条件逐一对比,然后返回满足条件的行数据。这样的数据查询会消耗大量的数据库系统时间,并造成大量磁盘I/O操作。因此,需要在数据表中建立类似于图书目录的索引结构,并将索引列的值及索引指针数据保存在索引结构中。此后在对数据表进行数据查询时,首先在索引结构中查找符合条件的索引指针值,然后再根据索引指针快速找到表中对应的数据记录,这样可快速检索数据记录。
索引是一种针对表中指定列的值进行排序的存储结构,使用它可以加快表中数据记录的查询速度。
在SQL中,使用DDL语句可完成索引对象的创建、修改、删除等操作。
基本语句格式为:
其中,CREATE INDEX为创建索引语句的关键词,<索引名>为在指定表中针对指定列创建索引的名称。该语句执行后,系统在表中为指定列创建其列值的索引,使用索引可实现对数据表的快速查询。
【例3-12】 在学生信息表(Student)中,为出生日期(BirthDay)列创建索引,以便支持按出生日期快速查询学生信息,其索引创建SQL语句为:
在PostgreSQL数据库管理工具中,通过执行上述语句,可以创建学生信息表的BirthDay_Idx索引,其运行结果界面如图3-11所示。
图3-11 执行学生信息表中BirthDay_Idx索引创建SQL语句及结果
在数据库表中,创建索引主要有如下好处:①可以大大加快数据的检索速度,这也是创建索引的最主要原因。②可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。③在使用分组和排序子句进行数据检索时,同样可以显著缩短查询中分组和排序的时间。
当然,在数据库表中,创建索引也会带来开销:①创建索引和维护索引要耗费时间,这种时间会随着数据量的增大而增加。②除了数据库表数据占用存储空间之外,索引数据也要占用一定的存储空间。③当对表中数据进行增加、删除和修改时,索引也需要动态维护,这样会降低数据的维护速度。
因此,在数据库系统开发中,需根据实际应用需求,仅对需要快速查询的数据库表相应列建立索引。此外,在数据库中,一般需要为每个表的主键列创建索引。
需要说明:CREATE INDEX语句所创建的索引,其索引值可能会有重复值。如果在应用中不允许有重复的索引值,则需要在创建索引的SQL语句中使用UNIQUE关键词,其格式如下:
使用SQL语句可以对索引对象进行修改操作,其中索引换名修改语句格式为:
其中,ALTER INDEX为索引对象修改语句的关键词,<索引名>为在数据库表中创建索引的名称,RENAME TO为索引换名关键词。该语句执行后,原有索引被换名为新名称。
【例3-13】 在学生信息表(Student)中,将原索引BirthDay_Idx更名BDay_Idx,其索引修改SQL语句为:
基本语句格式为:
其中,DROP INDEX为删除索引语句的关键词,<索引名>为被指定的索引名称。该语句执行后,系统会从表中删除该索引。
【例3-14】 在学生信息表(Student)中,删除BirthDay_Idx索引,其索引删除SQL语句为:
课堂讨论:本节重点与难点知识问题
1)在创建表的SQL语句中,如何定义代理键?
2)在创建表的SQL语句中,如何定义数据库表对象的实体完整性?
3)在创建表的SQL语句中,如何定义关联表的参照完整性?
4)在SQL中,如何使用DDL语句维护关系表?
5)在数据库表中是否创建索引,取决于哪些因素?
6)PostgreSQL数据库支持哪些索引类型?