3.1 解释外键、数据完整性和级联更新。
- 外键:已知X是关系R的主键,Y是关系S的属性/字段(或属性组/字段组),但不是S的主键。如果Y与X相对应,则称Y是关系S的外键。
这里有个容易弄错的地方:事实上无论是外键还是主键,它们可以是表中多个字段的集合(即Composite Key)。
- 数据完整性(数据库完整性):指数据的正确性和相容性。
- 数据的正确性:数据应该准确地反映现实世界中的事实,不应该包含任何错误的、不符合事实的信息。(举例:数据库中储存的日期"2023.16.36"破坏了正确性)
- 数据的相容性:数据在不同的关系中必须符合相应的逻辑关系。(举例:数据的参照完整性)
- 级联更新:对于涉及主键和外键的更新操作,不是简单的接收和拒绝,而是根据 实际应用的具体情况,在接受非违约更新的同时,把违约更新尽量转换为非违约更新,并 最终接受更新的处理方法。
3.2 简述数据完整性的内容及其约束规则。
数据完整性的内容:实体完整性、参照完整性和用户定义完整性。
- 实体完整性规则:主属性A的取值不能为空值(NULL)。
二级结论:主属性是指构成候选(复合)键的属性,因此主属性的值可以不唯一,而候选键的值则一定不为NULL且唯一。例如在储存图书购买记录的数据表中,用户ID和图书ID作为主属性构成了该表的一个候选键。显然用户ID和图书ID的取值都允许不唯一,但候选键(用户ID, 图书ID)必须唯一。
- 参照完整性规则:如果X是关系R的主键,Y是关系S的外键,且Y与X相对应,则Y的取值要么为空值,要么取X的值。
在这个定义中,R和S可以来自同一张表。举例:职工信息表中的"经理"字段的信息来自该表本身的主键字段"职工号"。
- 用户定义完整性规则:用户根据系统需求自己定义的约束条件。
3.3 简述完整性控制机制的基本功能。
定义功能、检查功能和违约处理。
-
定义功能:DBMS系统应支持用户在定义数据表结构的时候,就设置好实体/参照/用户数据完整性的约束条件。
-
检查功能:DBMS系统应支持用户在执行增删改操作时,校验变更的数据是否符合定义数据表时预设的数据完整性约束条件;对于违约操作,能够触发相应的违约处理。
-
违约处理:对于破坏数据完整性的违约操作,DBMS能够提供兜底措施以维护数据的完整性。
3.4 简述完整性的违约处理方法。
-
拒绝更新:直接抛出报错,不执行数据更新。
-
置空:对于违约操作涉及的数据,直接将其值置为NULL再存入数据库。
-
级联更新。
3.5 已知关系模式如下: 客户C(客户号CNo,客户名CName,地址CAddr)、产品P(产品号PNo,产品名PName,价格Price,供应商PSupp)、订单R(RNo,CNo,PNo,日期RDate,数量Quant)。 如果规定一张订单只能订购一种产品,请用SQL语言创建上述关系模式,并完成以下完整性约束:
- 定义相应的实体完整性。
- 定义相应的参照完整性。
- 定义价格区间为[20, 60)。
-- 以下代码均以postgresql v16为例
-- 建立一个名为happyou的数据库
create database happyou;
--打开数据库happyou
\c happyou
--建立客户表
create table C(
CNo char(6) primary key check (CNo ~ '^C[0-9]{6}$'),
CName char(8) not NULL,
CAddr char(22) not NULL
);
--建立产品表
create table P(
PNo char(6) primary key check (PNo ~ '^P[0-9]{6}$'),
PName char(20) not NULL,
Price decimal(5, 2) check(Price >= 20 and Price < 60),
PSupp char(26) not NULL
);
--建立订单表
create table R(
RNo char(6) primary key check(RNo ~ '^R[0-9]{6}$'),
CNo char(6),
PNo char(6),
RDate date,
Quant float,
foreign key(CNo) references C(CNo)
on delete cascade on update cascade,
foreign key(PNo) references P(PNo)
on delete cascade on update cascade
);
以上sql命令中的"on delete cascade"表示启用级联删除。当一张表的主键作为另一张表的外键,并启用级联删除时,当主表中的某条记录被删除时,会自动删除与之关联的外键表中的相关记录。
以上sql命令中的"on delete update"表示启用级联更新。当一张表的主键作为另一张表的外键,并启用级联更新时,当主表中的某条记录被更新时,外键表中对应的记录也会相应发生更新。
3.6 已知关系供应商S和零件P如表3.1和表3.2所示,其主键分别是供应商号和零件号,P的供应商号是P的外键,颜色只能取红、白或蓝。假设DBMS无级联功能。
供应商S表:
| 供应商号 | 供应商名 | 城市 |
|---|---|---|
| B01 | 红星 | 北京 |
| S10 | 宇宙 | 上海 |
| T20 | 黎明 | 天津 |
| Z01 | 立新 | 重庆 |
零件P表:
| 零件号 | 颜色 | 供应商号 |
|---|---|---|
| 010 | 红 | B01 |
| 011 | 蓝 | B01 |
| 201 | 蓝 | T20 |
| 312 | 白 | S10 |
(1)如果向P插入新元组(‘201’,‘白’,‘S10’)、(‘301’,‘红’,‘T11’)和(‘301’,‘绿’,‘B01’),则不能插入的元组是哪些?
(‘201’,‘白’,‘S10’)违反了数据的实体完整性规则,不能插入。
(‘301’,‘绿’,‘B01’)违反了数据的用户定义完整性规则,不能插入。
(2)如果删除S的元组(‘S10’,‘宇宙’,‘上海’)和(‘Z01’,‘立新’,‘重庆’),则可以删除的是哪些?
(‘S10’,‘宇宙’,‘上海’)不能删除,否则会导致P表中的参照完整性被破坏。
(‘Z01’,‘立新’,‘重庆’)可以删除。
(3)如果把S中供应商号的值‘Z01’改为‘Z30’,或者把P中供应商号的值‘T20’改为‘T10’,则可以执行的操作是哪些?
前者可以,后者不行,原因同前一题。
(4)S×P的元组个数是多少。
4 * 4 = 16个
(5)S与P自然连接后的元组个数是多少?
共4个元组,具体如下所示:
| 零件号 | 颜色 | 供应商号 | 供应商名 | 城市 |
|---|---|---|---|---|
| 010 | 红 | B01 | 红星 | 北京 |
| 011 | 蓝 | B01 | 红星 | 北京 |
| 201 | 蓝 | T20 | 黎明 | 天津 |
| 312 | 白 | S10 | 立新 | 重庆 |
3.7 已知雇员关系和部门关系如下。
雇员表:
| 雇员号 | 雇员名 | 部门号 | 工资 |
|---|---|---|---|
| 001 | 张三 | 02 | 2000 |
| 010 | 王宏 | 01 | 1200 |
| 056 | 马林 | 02 | 1000 |
| 101 | 张三 | 04 | 1500 |
部门表:
| 部门号 | 部门名 | 电话 | 地址 |
|---|---|---|---|
| 01 | 业务部 | 000 | A楼 |
| 02 | 销售部 | 001 | B楼 |
| 03 | 服务部 | 002 | C楼 |
| 04 | 财务部 | 003 | D楼 |
(1)雇员的主键是哪些属性?
雇员号
(2)雇员的外键是哪些属性?
部门号
(3)雇员名是雇员关系的候选键吗?
不是,因为雇员名可能存在重复,不符合数据的实体完整性规则。
(4)如果部门关系中,财务部的部门号需要调整为06,则雇员关系如何调整?
update 雇员表
set 部门号='06' where 部门号='04';
(5)把雇员马林调往服务部,则雇员关系如何调整?
update 雇员表
set 部门号='03' where 雇员名='马林';
3.8 已知关系R和S如表3.5和3.6所示。
R表:
| A | B | C |
|---|---|---|
| 1 | b1 | c1 |
| 2 | b2 | c2 |
| 3 | b1 | c1 |
S表:
| D | E | A |
|---|---|---|
| d1 | e1 | 1 |
| d2 | e2 | 1 |
| d3 | e1 | 2 |
(1)定义R和S的完整性约束。
create table R (
A int primary key,
B char(2) check(B ~ '^b[0-9]$'),
C char(2) check(C ~ '^c[0-9]$')
);
create table S (
D char(2) check(D ~ '^b[0-9]$'),
E char(2) check(E ~ '^c[0-9]$'),
A int,
foreign key(A) references R(A)
on delete cascade on update cascade
);
(2)在(1)的基础上,能否删除R中A的值分别为2和3的元组?说明原因。
可以。R表中主键字段A已启用级联删除/更新。当R中发生变更时,会在S表触发级联操作,不会破坏数据的参照完整性。