数据库完整性约束全解析:从理论到实践

一、静态完整性约束总体分类(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(7910

  • SC.Cno → Course.Cno(78

  • 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(第 35 题)

    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.

相关推荐
闪电悠米2 小时前
黑马点评-Redis 消息队列-03_stream_consumer_group
开发语言·数据库·redis·分布式·缓存·junit·lua
DIY源码阁2 小时前
JavaSwing航班订票管理系统 - MySQL版
数据库·mysql
浪客灿心4 小时前
项目篇:模块设计与实现
数据库·c++
流星白龙5 小时前
【MySQL高阶】26.事务(1)
数据库·mysql
三十..6 小时前
Redis 核心原理与高可用架构实践
运维·数据库·redis
这个DBA有点耶6 小时前
索引优化深潜(下):索引合并、ICP 与索引设计的实战法则
数据库·mysql·架构
努力努力再努力wz6 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
JdSnE27zv7 小时前
Qt 操作SQLite数据库
数据库·qt·sqlite
tedcloud1237 小时前
HyperFrames部署教程:用HTML生成MP4视频
前端·数据库·人工智能·html·音视频
布朗克1687 小时前
25 IO流高级操作——序列化、NIO与Files工具类
java·数据库·io·nio