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

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

相关推荐
Databend43 分钟前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent
ClouGence4 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
先吃饱再说21 小时前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils21 小时前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend1 天前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶1 天前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构
smallyoung1 天前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·mysql·postgresql
parade岁月1 天前
MySQL JOIN解析:朴实无华但食之有味
数据库·后端
用户3169353811831 天前
MySQL服务无法启动问题解决全记录
数据库
vivo互联网技术1 天前
从 10 分钟到 1 秒:ES 深度分页任意跳页的三轮优化实战
服务器·数据库·redis·elasticsearch·深度分页