数据库原理及应用_数据库基础_第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提供的约束的一些分析

相关推荐
呆呆小金人1 分钟前
SQL入门:正则表达式-高效文本匹配全攻略
大数据·数据库·数据仓库·sql·数据库开发·etl·etl工程师
白鲸开源1 小时前
(二)从分层架构到数据湖仓架构:数据仓库分层下的技术架构与举例
大数据·数据库·数据分析
好玩的Matlab(NCEPU)1 小时前
Redis vs RabbitMQ 对比总结
数据库·redis·rabbitmq
21号 11 小时前
16.MySQL 服务器配置与管理
服务器·数据库·mysql
我的offer在哪里1 小时前
MongoDB
数据库·mongodb
练习时长一年3 小时前
AI开发结构化输出
数据库
IvorySQL3 小时前
灾难恢复工具内核细节探究与分享
数据库·postgresql·开源
lypzcgf3 小时前
商城小程序数据库表结构文档
数据库·小程序·电商
jjw_zyfx4 小时前
Ubuntu上vue3 vite使用MBTiles搭建地图服务器
服务器·数据库·ubuntu
EndingCoder4 小时前
Node.js SQL数据库:MySQL/PostgreSQL集成
javascript·数据库·sql·mysql·postgresql·node.js