
数据库系统(上)
数据库系统(上)
基础篇
数据库概念
关系数据库
关系模型
SQL语句
设计篇
实现篇
1. 绪论
1.1 数据
数据是描述现实世界中各种具体事物或抽象概念的可存储编码,是信息的载体。
数据与其语义是不可分的。
1.2 数据库
是长期储存在计算机内、有组织的、可共享的数据集合
特征:
不是临时存储
按照一定的数据形式组织、描述、储存
可以为各种用户共享
数据库的类型:
按照数据类型:
简单结构数据库:如关系数据库,时、空数据库
复杂结构数据库:如图数据库
半结构化数据:如XML数据库
非结构化数据:如文本、音视频、图像等多媒体数据库
数据存储的方式
单机数据库
分布式数据库
并行数据库
数据存储的介质、时长
内存数据库、流数据库
1.3 数据库管理系统(DBMS)及其结构
数据库管理系统:管理数据库,支持应用的软件系统
DataBase Management System (DBMS)
定义、组织、存储、管理数据
数据操纵
确保数据正确、安全、完整
并发控制与事务处理
数据字典是数据库管理系统的信息中心。
1.4 数据库系统
对比数据库系统,文件系统有的几大缺点:
数据冗余和不一致:各数据文件之间没有有机的联系,相同信息可能存在于多个文件中,容易导致同一数据在不同副本中出现不一致的情况。
数据访问困难:传统文件处理环境不支持便捷且高效的数据获取方式,难以应对需求的快速变化。
数据孤立:数据分散在不同文件中,且这些文件可能具有不同的格式。要编写新的应用程序来检索适当的数据非常困难。
完整性问题:数据库系统存储的数据必须满足某些一致性约束。文件系统中,新约束的加入通常需要通过修改程序来体现,尤其是涉及多个文件时,问题更为复杂。
原子性问题:操作是原子的:为了确保数据一致性,一些操作要么全部发生,要么根本不发生。例如,转账操作在文件系统中很难确保这样的原子性。
并发访问异常:为了提高系统的性能并加快响应速度,许多系统需要允许多个用户同时更新数据。然而,在文件系统中,多个不同的应用程序可能同时访问数据,且事先没有协调,导致管理复杂。
安全性问题:并非数据库系统的所有用户都可以访问所有数据,但文件系统中往往缺乏这样的安全约束。此外,由于应用程序是即席加入到文件系统中的,因此难以实现严格的安全控制。
数据库系统 (DB + DBMS + 其他组件)
数据库系统按照特定的数据模型,将部门内的所有数据组织到一个统一的结构化数据库中,使得部门的数据不再是各自独立的,而是能够体现出数据之间的有机关联。
1.5 数据抽象
数据抽象是一种通过隐藏数据的复杂细节,简化用户与系统交互的技术。其主要作用在于屏蔽数据存储和维护的复杂性,使用户无需了解底层实现细节,专注于数据的逻辑使用。这种抽象过程可分为三个层次:
视图抽象(外模式):
数据抽象的第一层次是视图抽象,针对不同用户群体的需求,将现实世界中的数据抽象为多个逻辑结构,称为视图。每个视图代表用户关心的数据集合,多个视图共同构成了数据库的外模式。一个数据库可以有多个外模式。
例如,不同的部门(如财务处、宿管科、教务处)可以看到针对它们需求定制的视图,而不需要访问其他部门不相关的数据。
逻辑抽象(逻辑模式):
逻辑抽象是将所有外模式中的视图综合起来,抽象出整个数据库的逻辑结构。这一层次描述了数据库的概念模型,是数据库的统一逻辑视图,保证所有用户的数据需求都能够通过这个结构进行处理。
一个数据库只有一个逻辑模式,该模式全面反映所有用户关心的现实世界数据。
物理抽象(内模式):
数据的物理抽象是将逻辑模式进一步抽象为内模式,定义数据在物理存储设备上的存储方式。物理抽象的关键在于如何高效地组织和存储数据,如通过索引、压缩等技术。
数据库只有一个内模式,决定了数据的实际存储结构。
此外,数据抽象还确保了数据独立性,即系统能够在物理存储或逻辑结构变化时保持数据的外部表现不变:
物理数据独立性:
当内模式改变时(如更改存储方式),逻辑模式不必改变,应用程序不受影响。
逻辑数据独立性:
当逻辑模式改变时(如增加属性),外模式保持不变,应用程序也不必做出修改。
通过三层抽象和两级独立性,数据库系统实现了用户与数据存储之间的解耦,保证了系统的灵活性和可扩展性。
1.6 数据模型
根据数据建模的层次进行分类:
概念模型:也称信息模型,用于按照用户的观点来对数据和信息建模,主要用于数据库设计
逻辑模型:用于按照计算机系统的观点对数据建模,主要用于数据库管理系统的实现
物理模型:对数据的最底层抽象,描述数据在系统内部的表示方式和存取方法,是面向计算机系统的
根据数据模型的类型进行分类:
实体关系(E-R)数据模型:用于视图抽象和外模式的定义
面向对象(O-O)数据模型:用于视图抽象和外模式的定义,用于逻辑抽象和逻辑模式定义
关系数据模型:用于逻辑抽象和逻辑模式定义
对象关系 (O-R) 数据模型:用于逻辑抽象和逻辑模式定义
层次和网络数据模型:用于逻辑抽象和逻辑模式定义
数据库语言:
数据定义语言 (Data Description Language, DDL):由数据模型的数据结构确定
数据操纵语言 (Data Manipulation Language, DML):取决于数据模型的数据操作
数据控制语言 (Data Control Language, DCL):用户的权限授予与取消
1.7 数据库系统的发展
第一代数据库系统:层次和网状数据库系统
第二代数据库系统:关系数据库系统
1970年,E.F.Codd提出关系数据模型和理论,获得ACM图灵奖第三代数据库系统:面向对象数据模型,数据库技术与其他学科的技术内容互相结合
2. 关系数据库
2.1 关系模型
2.1.1 关系数据结构
属性(Attribute):用于表示关系表中的列,每个属性有独特的属性名和对应的属性值。
域(Domain):单个属性可能取值的集合,定义了单个属性的取值范围,称作 $D_i$ 。
关系(Relation):将所有属性域 $D_i$ 进行笛卡尔积所得到的集合,这个集合的子集就是关系。
关系的性质:属性值必须取原子值,每一个属性值都是不可分的数据项。
关系模式(Relation Schema)
关系数据库(Relational Database)
基本关系(又称基本表、基表):
由用户定义的,在数据库中实际存储的关系。
可以进行查询与更新(增、删、改)。
中间结果关系:
对关系进行查询产生的中间结果。
可以在数据库中临时或永久存储(由系统建立)。
只可查询,不可更新。
视图关系(简称视图,又叫虚表):
用户根据需要定义的关系。
定义在基本关系或视图上。
只有模式,没有实例。
没有对应的实际存储数据。
可查询,更新受限。
关系数据库模式:
一组关系模式的集合,表示为
DB = {R1, R2, ..., Rn}
,其中Ri
是第 i 个关系模式。
关系数据库实例:
对应于关系数据库模式
DB = {R1, R2, ..., Rn}
的关系数据库实例,是一组关系实例的集合,表示为DB = {I1, I2, ..., In}
,其中Ii
是Ri
的关系实例。
2.1.2 完整性约束
超码(Superkey) 是可以唯一标识关系中元组的属性集。例如,
Student(ID, Name, Email)
中的ID
可以唯一标识每个学生,因此是超码,ID + Name
也可以是超码。候选码(候选键) 是最小的超码,去掉任何属性都无法唯一标识元组。例如,
ID
和Email
在Student
表中都是候选码。主键(Primary Key) 是从候选码中选择的唯一标识符,通常选用值不易变化的属性。在
Student
表中,ID
可以作为主键。外键(Foreign Key) 用于建立表与表之间的关联。例如,
Grade(StudentID, CourseID, Score)
表中的StudentID
是外键,指向Student(ID)
表中的ID
,确保学生成绩关联到有效的学生记录。
实体完整性约束:
如果
A
是关系模式R(U)
的主键属性,则A
不能取空值。也就是说,在
R(U)
的任何一个实例关系中,不允许任何元组的主键属性A
为空值。这个约束保证了主键能够唯一标识元组,并且主键属性值不能为空。
例子:
在 Student(ID, Name, Email)
表中,ID
是主键,因此每个学生的 ID
都必须有值,不能为空,否则无法唯一标识每个学生。例如,Student(ID=NULL, Name='Tom', Email='tom@example.com')
是不允许的,因为 ID
为空。
关联完整性约束(参照完整性):
定义了主键和外键之间的关系约束规则。
设
X
是关系模式R(U)
中关于关系模式S(U')
的外键。如果X
是R(U)
中某个元组的外键值,那么要么X
为空值,要么S(U')
中必须存在一个元组,其X
的值等于该外键值。
例子:
在 Grade(StudentID, CourseID, Score)
表中,StudentID
是外键,指向 Student(ID)
。
如果某个成绩记录的
StudentID
为空,表示成绩没有关联到任何学生,这符合参照完整性。如果
StudentID
不为空,例如StudentID = 1001
,那么在Student
表中必须存在一个学生ID = 1001
,否则该记录违反了关联完整性。
2.1.3 关系运算
2.1.3.1 关系代数演算 - 基本
选择(σ)
例子:从学生表Student
中选择年龄大于 18 的学生。
概括:筛选满足条件的元组。σ(Age > 18)(Student)
投影(π)
例子:从学生表Student
中提取学生的姓名和学号。
概括:只保留特定的列,去掉重复。π(Name, ID)(Student)
并(∪)
例子:将CourseA
和CourseB
的学生列表合并。
概括:合并两个关系,去除重复项。CourseA ∪ CourseB
差(−)
例子:找出CourseA
中没有选CourseB
的学生。
概括:从一个关系中去除另一个关系中的元组。CourseA − CourseB
笛卡尔积(×)
例子:将学生表Student
和课程表Course
做笛卡尔积,生成所有学生和课程的组合。
概括:生成两个关系中每个元组的所有组合。Student × Course
重命名(ρ)
例子:将学生表Student
重命名为EnrolledStudent
。
概括:给关系或属性重命名。ρ(EnrolledStudent)(Student)
2.1.3.2 关系代数演算 - 附加与拓展
交(∩)
例子:找出同时选了 CourseA
和 CourseB
的学生。
概括:返回两个关系中都存在的元组。
运算:CourseA ∩ CourseB
结果:只保留同时在 CourseA
和 CourseB
中出现的学生列表。
θ 连接
例子:将 Student
表与 Enrollment
表按 StudentID
进行连接,并且只显示成绩大于 80 的学生及他们的课程。
概括:根据给定条件(如 <
, >
, =
等)连接两个关系。
运算:Student ⨝ (Student.StudentID = Enrollment.StudentID ∧ Enrollment.Score > 80)
结果:生成一个包含学生姓名、ID、课程及其成绩的关系表,但只显示成绩大于 80 的记录。
自然连接(⨝)
例子:将 Student
表与 Enrollment
表按 StudentID
进行连接,显示学生和他们的课程。
概括:通过共享属性连接两个关系,自动匹配相同属性值。
运算:Student ⨝ Enrollment
结果:生成一个包含学生姓名、ID、课程等的完整记录表,其中每个学生的课程信息与其关联。
除(÷)
例子:查找选了所有必修课程的学生。
概括:从一个关系中找到与另一个关系匹配的所有元组。
运算:Student ÷ RequiredCourses
结果:返回那些已选修了所有必修课程的学生列表。
赋值(:=)
例子:将 Student
表的查询结果赋值给一个新关系 EnrolledStudents
。
概括:将查询结果存储为新关系。
运算:EnrolledStudents := σ(Age > 18)(Student)
结果:创建一个名为 EnrolledStudents
的新关系表,包含所有年龄大于 18 岁的学生。
外连接(⟕)
例子:将 Student
表与 Enrollment
表进行左外连接,显示所有学生及他们的课程(包括未选课的学生)。
概括:保留连接中的所有匹配元组,以及一方的未匹配元组。
运算:Student ⟕ Enrollment
结果:生成一个包含所有学生的记录表,未选课的学生的课程信息为空。
广义投影
概括:将算术运算符作为投影的一部分,可以在投影的过程中对选定的属性进行算术操作,如加减乘除等。
例子:假设有一个员工关系 Employee(EmpID, Salary, Bonus)
,我们希望计算每个员工的总收入(工资和奖金的和)。可以通过广义投影实现:
运算:π EmpID, (Salary + Bonus) (Employee)
结果:我们只投影出 EmpID
和 (Salary + Bonus)
的计算结果,得出每个员工的总收入。
聚集
概括:对集合中的元素进行统计操作,常见的聚集操作包括求和、求均值、计数、最大值和最小值等。这些操作通常用于处理关系中多个元组的数据汇总。
例子:假设我们有一个关系 Sales(Salesperson, Region, SalesAmount)
,想要计算每个地区的销售总额,可以通过分组聚集实现:
运算:Region G sum(SalesAmount) (Sales)
结果:对关系 Sales
按 Region
分组,并对每个分组求 SalesAmount
的总和。
例题
银行关系:银行 (银行名, 所在城市, 资产量)
客户关系:客户 (客户名, 街道, 城市)
账户:账户 (账户号, 银行名, 余额)
贷款:贷款 (贷款号, 银行名, 贷款量)
存款人:存款人 (客户名, 帐户号)
贷款人:贷款人 (客户名, 贷款号)
以下是银行关系的关系代数运算示例的重新排版,并附上每个查询的答案:
查询额度超过 $1200 的所有贷款
运算:σ 贷款量 > 1200 (贷款)
解释:选择所有贷款量超过 $1200 的贷款记录。查询额度超过 $1200 的所有贷款号
运算:π 贷款号 (σ 贷款量 > 1200 (贷款))
解释:选择所有贷款量超过 $1200 的贷款号。查询所有在银行有存款或贷款的客户的名字
运算:π 客户名 (贷款人) ∪ π 客户名 (存款人)
解释:查询所有在银行有贷款或存款的客户的名字。查询所有在银行有贷款的客户的名字、贷款号及额度
运算:π 客户名, 贷款号, 贷款量 (贷款人 ⨝ 贷款)
解释:通过客户和贷款的连接,查询所有在银行有贷款的客户的名字、贷款号及贷款额度。查询至少在“哈尔滨”的所有银行有贷款的客户的名字
运算:π 客户名, 银行名 (贷款人 ⨝ 贷款) ÷ π 银行名 (σ 城市 = “哈尔滨” (银行))
解释:找到在哈尔滨所有银行都有贷款的客户。查询至少在“哈尔滨”的所有银行有贷款的客户的贷款记录,包括客户名、贷款号、银行名及贷款量
运算:π 客户名, 贷款号, 银行名, 贷款量 (贷款人 ⨝ 贷款 ⨝ (σ 城市 = “哈尔滨” (银行)))
解释:查询那些至少在哈尔滨所有银行有贷款的客户的详细贷款记录。查询至少在“哈尔滨”的所有银行有贷款的客户的名字及其在哈尔滨所有银行的贷款总额
运算:π 客户名, sum(贷款量) (贷款人 ⨝ 贷款 ⨝ (σ 城市 = “哈尔滨” (银行)) GROUP BY 客户名)
解释:找到在哈尔滨所有银行有贷款的客户及其贷款总额。
2.1.3.3 元组关系演算
查询贷款额度大于 $1200 的贷款号、银行名及贷款额度
解释:
这是查询贷款的完整信息,包括贷款号、银行名和贷款额度。意思是找出所有属于‘贷款’关系且贷款量大于 1200 的元组 ttt。
查询贷款额度大于 $1200 的贷款号
解释:
这是查询贷款号的元组关系演算。意思是找出满足条件的元组 ttt,使得存在一个元组 sss 属于‘贷款’关系,且该元组的‘贷款号’等于 ttt 的‘贷款号’,并且该元组的‘贷款量’大于 1200。
2.1.3.4 域关系演算
2.2 SQL 查询语言
由于这里自己可能有点太熟悉了,这里只列举一些我自己不会的地方,等临考试之前冲击一下。
2.2.1 DML 查询语句
SELECT:指定要查询的列。
FROM:指定查询的数据源(表或视图)。
WHERE:定义过滤条件,用于筛选记录。
GROUP BY:将查询结果按一个或多个列进行分组。
HAVING:对分组后的数据进行条件过滤。
ORDER BY:指定查询结果的排序顺序。
DISTINCT:去除查询结果中的重复值。
JOIN:用于连接多个表。
UNION:合并两个或多个查询的结果集。
LIMIT / OFFSET:限制返回记录的数量或跳过指定数量的记录。
AS:为查询结果中的列或表定义别名。
2.2.2 SELECT 子查询
常见的子查询类型:
带有 IN 谓词的子查询
带有 比较运算符 的子查询
带有 ANY 或 ALL 谓词的子查询
带有 EXISTS 谓词的子查询
FROM 子句中的子查询
带有 WITH 子句的子查询
标量子查询
2.2.3 SELECT 集合查询
并UNION、交INTERSECT、差EXCEPT
2.2.4 DML 增删改语句
2.2.5 SQL 视图
3. 数据库的安全性
用户标识和鉴定(Identification & Authentication)
存取控制(Access Control)
视图(Views)
审计(Audit)
加密存储(Encryption Storage)
用户标识与鉴别
用户标识与鉴别是系统提供的最外层安全保护措施,用于确认用户的身份。常见的鉴别方法包括:
静态口令:用户通过固定的密码进行身份验证。
动态口令:使用一次性密码或基于时间变化的密码。
生物特征鉴别:如指纹、面部识别等生物特征。
智能卡鉴别:通过智能卡进行身份验证。
存取控制机制
存取控制机制主要包括两个部分:
定义存取权限:数据库管理系统(DBMS)提供语言机制来定义用户的权限,这些权限经过编译后存储在数据字典中。
检查存取权限:当用户发出存取请求时,DBMS会查找数据字典,检查用户是否具有相应的权限。如果超出权限,系统将拒绝执行操作。
存取控制方法
自主存取控制(Discretionary Access Control, DAC):允许用户根据自身权限对不同的数据对象进行不同的存取控制,并可以将权限转授给其他用户。SQL通过
GRANT
和REVOKE
语句支持自主存取控制。强制存取控制(Mandatory Access Control, MAC):用户无法直接感知或控制数据的访问,适用于对数据有严格秘密分级的环境。每个主体和客体都有一个敏感度标记,系统根据标记级别控制访问权限。
授权与权限管理
授权
授权是指向用户授予操作数据库对象的权限。SQL中的GRANT
语句用于实现授权。例如:
GRANT SELECT ON TABLE Course TO Bob;
可以将权限授予一个或多个用户,PUBLIC
表示全体用户。拥有权限的用户可以将权限进一步授予其他用户,但不允许循环授权。
权限收回
权限收回通过REVOKE
语句实现,支持两种方式:
CASCADE:级联回收,连同传播的权限一并收回。
RESTRICT:存在级联回收时拒绝执行权限回收。
例如:
REVOKE UPDATE(Cno) ON TABLE Course FROM Bob;
数据库角色
角色是权限的集合,便于管理一组具有相同权限的用户。通过角色可以简化授权过程。常用的角色管理操作包括:
创建角色:
CREATE ROLE <角色名>;
给角色授权:
GRANT <权限> ON <对象> TO <角色>;
将角色授予用户:
GRANT <角色> TO <用户>;
收回角色权限:
REVOKE <权限> ON <对象> FROM <角色>;
收回角色:
REVOKE <角色> FROM <用户>;
审计
审计功能通过专用的审计日志记录用户对数据库的所有操作,帮助数据库管理员(DBA)追踪和重现导致数据库现有状态的事件,找出非法访问者。C2级以上的DBMS必须具备审计功能。
例如:
AUDIT ALTER, UPDATE ON SC;
NOAUDIT ALTER, UPDATE ON SC;
数据加密
数据加密是防止数据库中数据在存储和传输过程中失密的有效手段。加密的基本思想是将原始数据(明文)通过一定的算法转换为不可直接识别的格式(密文),未授权的人员无法解密和获取数据内容。
授权示例
授予用户Bob查询Course表的权限:
GRANT SELECT ON TABLE Course TO Bob;
授予用户Alice和Jim对Student表和SC表的所有权限:
GRANT ALL PRIVILEGES ON TABLE Student, SC TO Alice, Jim;
授予用户Bob查询Course表和修改课程号的权限,并允许他传播此权限:
GRANT SELECT, UPDATE(Cno) ON TABLE Course TO Bob WITH GRANT OPTION;
权限回收示例
收回用户Bob修改Course表中课程号的权限:
REVOKE UPDATE(Cno) ON TABLE Course FROM Bob;
收回用户Alice及其传播的在Student表中的所有权限:
REVOKE ALL PRIVILEGES ON TABLE Student FROM Alice CASCADE;
收回所有用户在SC表中的查询权限:
REVOKE SELECT ON TABLE SC FROM PUBLIC;
收回Bob传播在SC表中的查询权限:
REVOKE GRANT OPTION FOR SELECT ON TABLE SC FROM Bob;
强制存取控制(MAC)示例
假设有以下敏感度标记:
TS(绝密):最高级别
S(机密)
C(可信)
P(公开)
用户和数据对象的标记如下:
在MAC机制下,用户的许可证级别决定了其对数据对象的访问权限。例如,用户Bob的许可证级别为TS,他只能写入标记为TS的数据对象,不能写入其他级别的数据。
创建用户
创建用户通常由系统超级用户执行,使用CREATE USER
语句。例如:
CREATE USER Alice WITH PASSWORD 'password123';
新创建的用户通常具有以下三种权限之一:
CONNECT:只能登录数据库,不能创建新用户或模式,后续权限需由管理员授予。
RESOURCE:能创建基本表和视图,不能创建模式和新用户,可以将存取权限授予其他用户。
DBA:超级用户,拥有所有数据库对象的存取权限,可以创建新用户、模式、基本表和视图等。
创建角色
通过创建角色,可以将一组权限赋予多个用户,简化权限管理。例如:
CREATE ROLE instructor;
GRANT SELECT, UPDATE ON TABLE takes TO instructor;
GRANT instructor TO Bob, Alice, Jim;
收回角色权限:
REVOKE UPDATE ON TABLE takes FROM instructor;
REVOKE instructor FROM Bob;
4. 数据库的完整性
数据库完整性是为了确保数据库中数据的正确性和相容性而提出的约束条件或规则。它能够保证数据库中的数据在插入、删除、更新等操作过程中维持一致性。
完整性约束的种类
数据库完整性约束通常包括以下四种:
域完整性
实体完整性
关联完整性(参照完整性)
用户定义完整性
在关系模型中,域完整性、实体完整性和关联完整性是必须满足的约束条件。
DBMS提供的完整性功能
为维护数据库完整性,数据库管理系统(DBMS)必须具备以下功能:
定义完整性约束条件的机制
完整性检查方法
违反约束时的处理方法
域完整性
域完整性是为了保证关系表中属性的取值合理性。例如:
属性值必须在指定的域中
某些属性是否允许为
NULL
某些属性是否必须唯一
属性的默认值设置
域完整性检查
域完整性通过以下方式检查:
CHECK:检查属性值是否符合某个布尔表达式
DEFAULT:设置属性的默认值
NOT NULL:要求属性值不为空
UNIQUE:确保属性列中的值唯一
示例
在创建SC表时,要求Sno
、Cno
、Grade
属性不允许为空值:
CREATE TABLE SC (
Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT NOT NULL,
PRIMARY KEY (Sno, Cno)
);
在创建部门表时,要求部门名称Dname
列值唯一,且部门编号Deptno
列为主码,Location
的默认值为‘哈尔滨’:
CREATE TABLE DEPT (
Deptno NUMERIC(2),
Dname CHAR(9) UNIQUE,
Location CHAR(10) DEFAULT '哈尔滨',
PRIMARY KEY (Deptno)
);
实体完整性
实体完整性是指关系中的主码(Primary Key)必须满足以下条件:
主码不能重复
主码不能取空值
主码定义示例
在Student
表中定义Sno
为主码:
列级定义主码:
CREATE TABLE Student (
Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
表级定义主码:
CREATE TABLE Student (
Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno)
);
关联完整性(参照完整性)
关联完整性是通过外键(Foreign Key)来维持的,确保不同关系表中的数据相容。外键参照另一个关系表的主键,保证数据的相互关联性。
关联完整性定义
在SC
表中,Sno
和Cno
作为外键分别引用Student
和Course
表的主键:
CREATE TABLE SC (
Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno, Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno)
);
用户定义的完整性
用户定义完整性是指数据库中用户可以根据实际需求定义的额外约束条件,常见的约束包括:
NOT NULL:确保属性值不为空
UNIQUE:确保属性值唯一
CHECK:设置属性值必须满足特定条件
示例
在创建Student
表时,定义Ssex
属性只能取值“男”或“女”:
CREATE TABLE Student (
Sno CHAR(9) PRIMARY KEY,
Sname CHAR(8) NOT NULL,
Ssex CHAR(2) CHECK (Ssex IN ('男', '女')),
Sage SMALLINT,
Sdept CHAR(20)
);
在SC
表中,Grade
属性的值必须在0到100之间:
CREATE TABLE SC (
Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT CHECK (Grade >= 0 AND Grade <= 100),
PRIMARY KEY (Sno, Cno)
);
完整性约束命名子句
在创建完整性约束时,可以为其命名,便于后续操作。语法如下:
CONSTRAINT <完整性约束条件名> <完整性约束条件>
示例
在Student
表中为约束条件命名:
CREATE TABLE Student (
Sno NUMERIC(6) CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999),
Sname CHAR(8) CONSTRAINT C2 NOT NULL,
Ssex CHAR CONSTRAINT C3 CHECK (Ssex IN ('男', '女')),
Sage SMALLINT CONSTRAINT C4 CHECK (Sage < 30),
CONSTRAINT StudentKey PRIMARY KEY (Sno)
);
可以通过以下命令删除或修改约束:
ALTER TABLE Student DROP CONSTRAINT C1;
ALTER TABLE Student ADD CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999);
断言(Assertion)
断言用于定义更复杂的约束,涉及多个表或聚合操作。对断言所涉及关系的操作将触发数据库管理系统(DBMS)的检查,任何违反断言的操作都会被拒绝。
示例
限制每个学期每门课程最多由100名学生选修:
CREATE ASSERTION SC_MAXSIZE
CHECK (100 >= ALL (SELECT COUNT(*) FROM SC GROUP BY Cno, Semester, Year));
触发器(Trigger)
触发器是一种事件驱动的特殊过程,用户定义在表上。当满足某些条件时,触发器会被自动执行。
触发器的定义语法
CREATE TRIGGER <触发器名>
{BEFORE | AFTER} <触发事件> ON <表名>
FOR EACH {ROW | STATEMENT}
[WHEN <触发条件>] <触发动作体>;
触发事件可以是INSERT
、DELETE
或UPDATE
,也可以是多个事件的组合。触发器按照粒度分为:
行级触发器(FOR EACH ROW)
语句级触发器(FOR EACH STATEMENT)
示例
定义一个在SC
表上,当Grade
更新时自动修改学生的总学分的触发器:
CREATE TRIGGER creditor AFTER UPDATE OF grade ON sc
REFERENCING OLD ROW AS orow, NEW ROW AS nrow
FOR EACH ROW
WHEN (orow.grade IS NULL OR orow.grade < 60) AND nrow.grade >= 60
BEGIN ATOMIC
UPDATE student
SET Total_Credit = Total_Credit + (SELECT Credit FROM course WHERE Cno = nrow.Cno)
WHERE Sno = nrow.Sno;
END;
通过域完整性、实体完整性、关联完整性和用户定义完整性,可以保证数据库中的数据保持一致、正确和相容性。DBMS提供的约束、触发器和断言等机制,进一步确保了数据操作的合规性和完整性。