数据库原理及应用_数据库基础_第4章关系模型的基本理论_数据库完整性规则和MySQL提供的约束

前言

"<数据库原理及应用>(MySQL版)".以下称为"本书"中4.2.1节和4.2.2节内容

引入

数据库完整性是指数据的正确性和相容性.利用完整性约束,DBMS可帮助用户阻止非法数据的输入

4.2.1 三类完整性规则

这一小节内容就这样读,也挺抽象.代入两个例子就容易理解了.

1.实体完整性规则

分析的结果就是规则4.1:主键的各个属性都不能为空值.

2.参照完整性规则

本书P105中间:参照完整性规则就是定义外键与主键之间的引用规则.

有几个概念:主键,外键,参照关系和被参照关系.其中主键和外键的概念前面已叙述.参照关系是指:当关系A拥有主键a和外键b.关系B用关系A的外键b作为主键时,称为关系A是参照关系,关系B是被参照关系.如图

|----------|-----|----------|---|----------|-----|---|
| | 关系A | | | | 关系B | |
| 属性1(主键a) | 属性2 | 属性3(外键b) | | 属性1(外键b) | 属性2 | |

简单理解:参照关系作为两个关系中的主要关系,先满足关系A,再满足关系B

规则4.2:外键或者取空值NULL,或者等于被参照关系中的主键的某个值.

**---**规则4.2是结论,通过两个例子去理解.

例1中的专业号是外键.对于参照关系(学生表)而言,学生可以没选专业(此时是NULL),如果选了专业,其专业号取值必须和被参照关系(专业表)中专业号在同一个域里(必须符合其中一个值).

例2中参照关系和被参照关系是同一个关系.如果班长没选出来,此项取值NULL.如果选出来了,则必有"班长学号"的取值和主键(学号)取值中的一个值相等.原因班长必是学生中的一员

一句话总结:外键取值优先,可以为NULL.

3.用户定义完整性规则

规则4.3 属性的取值应当满足用户定义的约束条件.

综上所述,三类完整性对应了3条规则.这是设计者提出的需求,且由SQL语言提供实现

本书P105最后一段:DBMS应该提供定义和检验这类完整性的机制(例如约束、触发器等) .以便用统一方法来处理它们,而不应该由应用程序来承担这个功能.

**---**前面帖子中讲过应用程序(高级语言)有丰富的逻辑表达能力和数据控制能力,但是在和数据库交互中,他所做的事是把参数传入SQL,调用SQL函数(通常是SELECT),提取返回值.并不能在建立表和传入表数据时产生各种约束.所以实际上应用程序想承担这个功能都不行.

例4-1 参照完整性规则的变通

这里是对参照完整性的一点补充:

1)外键和主键可以不同名,只要值域相同

**---**笔者对此感到困惑.如果外键不同名岂不是会产生误会吗?所以尽量别这样做,保持同名.

2)依赖关系和参照关系可以是同一个关系

**---**这点前面已经表达过.注意,这里的外键不管是表示"先修"还是"后继",结果都是一样的(他的外键是PC#),PC#取值可以是NULL,或者是C#中的某个值.原因不管先修还是后继课程,都是课程的一种.

3)外键取值和第2)意思相同.

4.2.2MySQL提供的约束

包括了主键约束,唯一约束,检查约束,外键约束.

1.主键约束(PRIMARY KEY)

目的:值唯一,非空

添加方法:见本书P106,P107.++推荐使用表级PRIMARY KEY约束++.

复制代码
/*表级主键约束*/
CREATE TABLE employee(
    empno         DECIMAL(2),
    name          VARCHAR(8),
    age           DECIMAL(3),
    deptno        DECIMAL(2),
    CONSTRAINT    pk_no PRIMARY KEY(empno)
);

调试:不输入empno,不能通过如下图所示

当输入正确的empno格式后,通过如下图所示

修改主键约束:创建表后添加主键约束,或者删除主键约束也可以,和表操作相同(ALTER语句)

2.唯一约束

唯一约束用于候选键的约束.

候选键本身没多大存在感,他的操作和主键约束差不多,注意可有一个空值(多个属性且无主键),

建立一个新表employee2,添加唯一约束,phone和name,即表示2个人可以用一个手机号码或者2人可重名

复制代码
/*表级主键和唯一约束*/
CREATE TABLE employee2(
    empno         DECIMAL(2),
    name          VARCHAR(8),
    age           DECIMAL(3),
    deptno        DECIMAL(2),
    phone         VARCHAR(12),
    CONSTRAINT    pk_no PRIMARY KEY(empno),
    CONSTRAINT    emp_phone UNIQUE(phone,name)
);

以下是测试结果:

第5项可以添加是没想到的:两个键组成的唯一约束,两个输入NULL都可以,对于这个情况,一是用得不多不用纠结.二考虑在有主键存在的情况下,唯一约束可以都为空,因为有主键保证唯一性

3.检查约束

目的:通过检查输入表中的数据来维护用户定义的完整性.

关键词:CHECK指令

例4-5:建立employee表,限制age字段的值必须大于20且小于60.

复制代码
CREATE TABLE employee2(
    empno         DECIMAL(2),
    name          VARCHAR(8),
    age           DECIMAL(3),
    deptno        DECIMAL(2),
    phone         VARCHAR(12),
    CONSTRAINT    pk_no PRIMARY KEY(empno),
    CONSTRAINT    age_CK CHECK(age>20 AND age<60)
);

输入一个不满足条件的年龄:18,以下是测试结果:

输入满足条件的年龄:22,以下是测试结果:

修改检查约束:创建表后添加检查约束,或者删除检查约束也可以,和表操作相同(ALTER语句)

4.外键约束

本书P109:外键约束涉及两个表,即主表和从表.从表是指外键所在的表,主表是指外键在另一张表中作为主键的表.

**---**这里的两个概念:主表和从表一定要区分清楚.像笔者这样记忆力不好的特别要注意别弄混了.

主表其实是前面说过的"被参照关系",从表是"参照关系".这里做两点理解:

1>从表中的外键值受主表限制,可以取NULL或主表中对应的值;

2>从表的外键值可以相同.

笔者在这里用两个表来说明主表和从表,记住这两个表,很容易对主表和从表做出判定:

|--------|----|----|-----------|---|---------|-------|--------|----|
| 学生表(主表) |||| | 选课表(从表) ||||
| 学号(主键) | 姓名 | 性别 | 出生日期 | | 课程号(主键) | 课程名 | 学号(外键) | 成绩 |
| 1001 | 张三 | 男 | 1980/4/30 | | 75001 | 电影鉴赏 | 1001 | 95 |
| 1002 | 李四 | 男 | 1980/8/30 | | 75002 | 中国古文学 | 1001 | 96 |

从表的外键值可以相同.在这里的表现就是张三选修了两门课

此外主表可以看成从表的"基石",++从表外键取值必须从主表的主键值中选取(或者NULL)++

主表主键操作对从表的影响

1)插入:无影响

2)修改:若从表中的外键值与主表中的主键值一样,则有影响

3)删除:同上,可能有影响

从表外键操作对完整性的影响

1)插入:受从表主键值的约束

2)修改:同上,受从表主键值的约束

3)删除:无影响

主表和从表重在理解,上面的几点不用刻意去记.

例4-6

建立两个表employee和department,实现两个表的外键约束,并指定级联更新和级联删除

复制代码
CREATE TABLE department(
    deptno         DECIMAL(5),
    dept_name      VARCHAR(16), 
    CONSTRAINT     dp_no PRIMARY KEY(deptno)
);

CREATE TABLE employee2(
    empno         DECIMAL(5)  PRIMARY KEY,
    ename         VARCHAR(10) NOT NULL,
    age           DECIMAL(3),
    deptno        DECIMAL(5),
    CONSTRAINT    FK_ID FOREIGN KEY(deptno) REFERENCES department(deptno) ON UPDATE CASCADE,
    CONSTRAINT    FK_IG FOREIGN KEY(deptno) REFERENCES department(deptno) ON DELETE CASCADE
);

注意:这里把级联更新和级联删除放在一起.注意用CONSTRAINT给外键命名时,需要不同的名称,否则报错.

生成下面两个表

表1:department(主表)

表2:employee2(从表)

然后笔者进行了两步操作:

1.删除级联更新的外键约束

复制代码
/*删除级联更新FK_IG*/
ALTER table employee2 DROP FOREIGN KEY FK_IG;

2.把department中的数据修改

刷新后NaviCat Premium lite17 崩溃了,重新打开后,表employee2内的数据发生了变化

级联更新发生了,但是把其他数据给删除了,原因暂时未知.

启示

先不管什么原因造成的,以此看出数据库操作要小心,及时做好备份.每一步操作都能回溯.

修正

重新建立employee2表如下:

复制代码
CREATE TABLE employee2(
    empno         DECIMAL(5)  PRIMARY KEY,
    ename         VARCHAR(10) NOT NULL,
    age           DECIMAL(3),
    deptno        DECIMAL(5),
    CONSTRAINT    FK_ID FOREIGN KEY(deptno) REFERENCES department(deptno) ON UPDATE CASCADE
);

生成数据

修改department表

关闭软件再打开软件,点开employee2表

修改成功

原因探寻

1.软件问题.这个笔者并不太熟,是可能原因

  1. 是否只允许提交一个外键,多个外键冲突?

3.从语义上看cascade和set null有冲突.cascade和no action或许可以同时用.有机会可以试试

小结

数据库完整性规则和MySQL提供的约束的一些分析

相关推荐
majunssz4 小时前
深入剖析Spring Boot依赖注入顺序:从原理到实战
java·数据库·spring boot
比特森林探险记4 小时前
MySQL 架构全景解析
数据库·mysql·架构
数字冰雹5 小时前
图观 流渲染场景服务器
服务器·前端·数据库·数据可视化
pccai-vip5 小时前
系分论文《论非关系型数据库(NoSQL)在社交媒体内容管理系统中的应用》
数据库·nosql·媒体
谱写秋天5 小时前
软考-系统架构设计师 NoSQL数据库详细讲解
数据库·系统架构·软考架构师
观望过往5 小时前
非关系型数据库(NoSQL):特性、类型与应用指南
数据库·nosql
阿巴~阿巴~6 小时前
MySQL复合查询(重点)
服务器·数据库·sql·mysql·ubuntu
帧栈6 小时前
开发避坑指南(61):Redis持久化失败:RDB快照因磁盘问题无法保存解决方案
数据库·redis·缓存
瀚高PG实验室7 小时前
Navicat导入Excel至瀚高数据库
数据库·excel·瀚高数据库