一、静态完整性约束总体分类(Static Integrity Constraints)
在关系数据库中,静态完整性约束主要包括:
1️⃣ 实体完整性(Entity Integrity)
核心规则:
-
主键(PRIMARY KEY)非空且唯一
-
一张表只能有一个主键(可以是复合主键)
实验中体现:
-
Student(Sno) 主键
-
Dept(Dno) 主键
-
Course(Cno) 主键
-
Teacher(Tno) 主键
-
SC(Sno, Cno) 复合主键(第 [3] 题)
SQL 示例:
CONSTRAINT pk_student PRIMARY KEY(Sno)
CONSTRAINT pk_sc PRIMARY KEY(Sno, Cno)
2️⃣ 参照完整性(Referential Integrity / 外键)
核心规则:
-
外键值必须是被参照表主键的有效值 或 NULL
-
可定义参照动作:
-
CASCADE(级联)
-
NO ACTION(拒绝)
-
SET NULL
-
SET DEFAULT
-
实验中体现:
-
SC.Sno → Student.Sno([7][9][10])
-
SC.Cno → Course.Cno([7][8])
-
Student.Dno → Dept.Dno([14])
-
Teacher.Dno → Dept.Dno([16])
-
Course.Tno → Teacher.Tno([15])
SQL 示例:
ALTER TABLE SC
ADD CONSTRAINT fk_sc_sno FOREIGN KEY(Sno) REFERENCES Student(Sno)
ON DELETE CASCADE ON UPDATE CASCADE;
关键现象:
-
级联更新(UPDATE CASCADE)
-
级联删除(DELETE CASCADE)
-
插入非法外键值被拒绝
3️⃣ 域完整性(Domain Integrity)
核心规则:
-
列的数据类型
-
NOT NULL
-
DEFAULT
-
CHECK 约束
(1)默认值约束(DEFAULT)
实验体现:
-
SC.Score 默认为 0(第 [3][5] 题)
Score float(1) DEFAULT 0
(2)CHECK 约束
实验体现:
-
Gender ∈ {'F','M'}([12])
-
Age BETWEEN 12 AND 30([13])
-
Credit BETWEEN 0 AND 5([15])
-
Hours / Credit = 20([15])
-
Salary − Deduction > 0([16])
CHECK(Gender IN ('F','M'))
CHECK(Salary - Deduction > 0)
4️⃣ 唯一性约束 / 候选键(Alternate Key / UNIQUE)
核心规则:
-
除主键外,其他列或列组合也必须唯一
-
可包含 NULL(但只能出现一次)
实验体现:
-
Dept.Dname UNIQUE(cst_dept_unique_001)
-
(Sname, Haddress) 作为 Student 的候选键([11])
CONSTRAINT cst_dept_unique_001 UNIQUE(Dname)
ALTER TABLE Student ADD CONSTRAINT cst_student_unique_001 UNIQUE(Sname, Haddress);
二、其他重要关联知识点
1️⃣ 复合主键(Composite Primary Key)
-
SC(Sno, Cno) 共同构成主键
-
防止同一学生重复选同一门课
2️⃣ NULL 值在约束中的行为
-
主键 不允许 NULL
-
外键 允许 NULL(除非显式 NOT NULL)
-
UNIQUE 列允许一个 NULL(SQL Server)
实验体现:
- 最初 SC 表插入 NULL 学号成功([1])
3️⃣ 约束违反时的系统行为
-
INSERT / UPDATE 被拒绝
-
报错信息提示约束名
-
事务回滚(单条语句)
4️⃣ 约束命名规范(实验强调)
-
pk_ 主键
-
fk_ 外键
-
cst_ 自定义 CHECK / UNIQUE
意义:
-
便于维护
-
明确错误来源
四、Experiment Overview
1. 实验目的
**CN:**
本实验旨在理解并应用关系数据库中的静态完整性约束,包括实体完整性、参照完整性、域完整性和用户自定义完整性。
五、Experiment Content
1. 创建数据库与数据表
CREATE DATABASE SCT;
GO
USE SCT;
GO
CREATE TABLE Student(
Sno char(10) CONSTRAINT pk_student PRIMARY KEY,
Sname varchar(20),
Gender char(2),
Age int,
Dno char(2),
Haddress varchar(100)
);
CREATE TABLE Dept(
Dno char(2) CONSTRAINT pk_dept PRIMARY KEY,
Dname varchar(20) CONSTRAINT cst_dept_unique_001 UNIQUE,
Dean varchar(20)
);
CREATE TABLE Course(
Cno char(3) CONSTRAINT pk_course PRIMARY KEY,
Cname varchar(30),
Hours int,
Credit float(1),
Tno char(3)
);
CREATE TABLE Teacher(
Tno char(3) CONSTRAINT pk_teacher PRIMARY KEY,
Tname varchar(30),
Dno char(2),
Title varchar(20),
Salary float(1),
Deduction float(1)
);
CREATE TABLE SC(
Sno char(10),
Cno char(3),
Score float(1)
);
GO
2. SQL 操作、执行结果与解释
[1] 向 SC 表中插入 (NULL, '005', 88)
INSERT INTO SC VALUES(NULL, '005', 88);
**Result / 结果:** ✅ Success / 成功
**CN:**
此时 SC 表未定义主键和外键约束,因此允许 NULL 值以及不存在的课程编号。
[2] SC 表中出现重复元组
INSERT INTO SC VALUES('2015030101','001',80);
**Result / 结果:** ✅ Success / 成功
**CN:**
在没有主键的情况下,SQL Server 允许表中存在完全重复的数据行。
[3] 删除并重建 SC 表,设置主键与默认值
DROP TABLE SC;
CREATE TABLE SC(
Sno char(10),
Cno char(3),
Score float(1) DEFAULT 0,
CONSTRAINT pk_sc PRIMARY KEY(Sno, Cno)
);
✅ Success / 成功
[4] 插入合法元组
INSERT INTO SC VALUES('2015030101','001',80.0);
INSERT INTO SC VALUES('2015030102','002',96.0);
✅ Success / 成功
[5] 使用默认成绩插入数据
INSERT INTO SC(Sno, Cno) VALUES('2015040101','001');
SELECT * FROM SC;
**Result / 结果:**
Score = 0
**CN:**
DEFAULT 约束自动将成绩赋值为 0。
[6] 插入不存在的课程
INSERT INTO SC VALUES('2015040101','009',76);
✅ Success / 成功
**CN:**
当前尚未定义外键约束,因此允许插入。
[7] 添加外键约束
ALTER TABLE SC
ADD CONSTRAINT fk_sc_sno FOREIGN KEY(Sno) REFERENCES Student(Sno)
ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE SC
ADD CONSTRAINT fk_sc_cno FOREIGN KEY(Cno) REFERENCES Course(Cno)
ON DELETE CASCADE ON UPDATE CASCADE;
✅ Success / 成功
[8] 添加外键后再次插入非法课程
INSERT INTO SC VALUES('2015040101','009',76);
❌ Failure / 失败
**CN:**
违反了外键约束 fk_sc_cno,课程编号不存在。
[9] 级联更新
UPDATE Student SET Sno = '2015030110' WHERE Sno = '2015030101';
SELECT * FROM SC;
**CN:**
✅ SC 表中的 Sno 同步更新(CASCADE)
[10] 级联删除
DELETE FROM Student WHERE Sno = '2015030110';
SELECT * FROM SC;
**CN:**
✅ SC 表中相关记录被级联删除。
[11] 候选键约束冲突
sql
ALTER TABLE Student
ADD CONSTRAINT cst_student_unique_001 UNIQUE(Sname, Haddress);
INSERT INTO Student VALUES('2015030103','Li Jian','M',20,'03','No. 55, Huangchengxi Road, Wenzhou');
❌ Failure / 失败
**Reason:** Duplicate alternate key value.
[12] 性别检查约束
ALTER TABLE Student
ADD CONSTRAINT cst_student_gender CHECK(Gender IN ('F','M'));
INSERT INTO Student VALUES('2015030104','Wang Tao','X',20,'03','Hangzhou');
❌ Failure / 失败
[13] 年龄约束
ALTER TABLE Student
ADD CONSTRAINT cst_student_age CHECK(Age BETWEEN 12 AND 30);
INSERT INTO Student VALUES('2015030105','Zhao Min','F',35,'03','Ningbo');
❌ Failure / 失败
[14] 学生表外键 Dno
ALTER TABLE Student
ADD CONSTRAINT fk_student_dno FOREIGN KEY(Dno) REFERENCES Dept(Dno)
ON DELETE CASCADE ON UPDATE CASCADE;
❌ Failure when inserting invalid department number.
[15] 课程表约束
ALTER TABLE Course ADD CONSTRAINT cst_course_credit CHECK(Credit BETWEEN 0 AND 5);
ALTER TABLE Course ADD CONSTRAINT fk_course_tno FOREIGN KEY(Tno) REFERENCES Teacher(Tno)
ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE Course ADD CONSTRAINT cst_course_hours_credit CHECK(Hours/Credit = 20);
❌ Violation example: Hours = 50, Credit = 2 → 50 / 2 ≠ 20
[16] 教师表约束
ALTER TABLE Teacher ADD CONSTRAINT fk_teacher_dno FOREIGN KEY(Dno) REFERENCES Dept(Dno)
ON DELETE NO ACTION ON UPDATE NO ACTION;
ALTER TABLE Teacher ADD CONSTRAINT cst_teacher_salary_deduction CHECK(Salary - Deduction > 0);
❌ Failure occurs when Salary ≤ Deduction.