一言
镇生者之魂,安亡者之心,赎未亡之罪,轮未竟之回。——镇魂
数据库系统概论笔记:第五章:数据库完整性
本文最后更新于 510 天前,其中的信息可能已经有所发展或是发生改变。

概念:指数据的正确性和相容性

  • 完整性:指数据符合现实世界的语义(比如学号必须唯一)

  • 相容性:指数据库中同一对象在不同关系表中是符合逻辑的(学生选的课必须存在与选课表中)

5.1到5.3在之前的第三章都基本学过。

5.1 实体完整性

5.1.1 定义

  • 关系模式的实体完整性:设置主码 primary key

  • 单属性:可以在列级和表级进行定义:例:sno char(10)primary key or primary key(sno)

  • 多属性:只能在表级 例:primary key(sno,cno)

5.1.2 实体性完整性检查和违约处理

  1. 完整性检查:每当主码列进行更新后,

    1. 检查主码值是否唯一,如果不唯一则拒绝修改

    2. 检查各个属性是否为空,只要有一个为空就拒绝修改

  2. 检查主码方式:全盘扫描,全盘扫描是十分耗时的,关系数据库管理系统一般都会采取B+数索引(详情请转数据结构)

5.2 参照完整性

5.2.1定义

  • 定义:设置外码 例:foreign key(xxx) reference 表名(xxx)表级

  • foreign:外国的,涉外的

  • reference:参考

5.2.2 参照性完整性检查和违约处理

参照性完整性将两个表中的相应元组联系起来了


违约处理规则:

  • 拒绝:一般为默认策略

  • 级联:当删除或者修改被参照表中的一个元组时,使得与参照表不一样的时候,则将参照表中对应的元素也修改了 通俗点:你参照人家的,人家改了,你这也得改

  • 设置为空值:当删除或者修改被参照表中的一个元组时,使得与参照表不一样的时候,则将参照表中对应的属性设置为空值。人家改了或者删了,我也有不参考他的权力,那我也就置为空了

SQL中使用级联、拒绝、设为空

foreign key(sno) reference student(sno)//sno是sc表中参照与student表的元素
on delete cascade //当删除student中的元组时,删除sc表中对应的元组
on update cascade//当更新student表中的sno时,更新sc表中的元素
foreign key(cno) reference course(cno)
on delete no action//当删除course表中的元组造成与sc表中不一致时,拒绝删除

5.3 用户定义的完整性

5.3.1属性上的约束条件

  • 非空 not null

  • 列值唯一 unique

  • 检查列值 check短语

如果不满足直接拒绝执行

5.3.2 元组上的约束条件

上边上的check是对每一列

当然也可以在整个元组进行检查

写在最后而不是在某一属性的后边

当违约之后拒绝执行

5.4 完整性约束命名字句

格式:

constraint <完整性约束条件名>< 完整性约束条件>

完整性约束条件包括: not null unique primary key check foreign reference 等等

例:

sage char(3);
constraint  C1 check(sage<30);
constraint studentkey primary key(sno);

这样做有什么意义呢?

这样做方便维护,当后期想修改这个完整性约束的字句的时候,就可以先删除,再修改

例如:

ALTER TABLE student
    DROP CONSTRAINT C1;
ALTER TABLE student
    ADD CONSTRAINT C1 CHECK(sage<40);

5.5 域中的完整性限制

域是一组具有相同数据类型的值的集合

例:

CREATE DOMAIN GenderDomain CHAR(2)
    CONSTRAINT GD CHECK(VALUE IN('男','女'));
 //之后,在所有的性别后边的限制条件就可以加上:
 Ssex GenderDomain;

这样就OK了

同理,想修改的话,

也是先用ALTER......DROP......先删除GD这个条件限制

然后 ALTER......ADD......加上新的,就可以了

5.6断言

CREATE ASSERTION <断言名> <check字句>

所谓断言,就是创建一个快捷查询条件

CREATE ASSERTION test
    CHECK(60>=ALL(select count(*)
                    FROM SC
                    GROUP by cno)
                    );

5.7触发器

定义:是用户定义再关系表上的一类由事件驱动的特殊过程

5.7.1 定义触发器:

格式:

CREATE TRIGGER<触发器名>
{BEFORE|AFTER}<触发事件>ON <表名>
REFERENCING NEW|OLD ROW AS<变量>
FOR EACH{ROW|STATEMENT}
[WHEN<触发条件>]<触发动作>

说明:

  1. 表的拥有者才可以在表上创建触发器

  2. 触发器名:

    1. 同一模式下,触发器名必须是唯一的,触发器名和表名必须在同一模式下
  3. 表名:

    1. 触发器只能定义在基本表上,不能定义在视图上
  4. 触发事件:

    1. INSERT、DELETE 、UPDATE这三个事件可以触发事件,也可以是这三个事件的组合

    2. 或者是UPDATE OF<触发列>

    3. AFTER/BEFORE表示触发时机

    4. ALTER触发事件操作执行之后激活触发器

    5. BEFORE表示操作执行之前激活触发器

  5. 触发器类型

    1. 行级触发器:FOR EACH ROW

    2. 语句级触发器:FOR EACH STATEMENT

  6. 触发条件:当WHEN触发条件为真时,才执行触发动作,如果没有触发条件,则触发器激活后立即执行触发动作

  7. 触发动作体

    1. 可以是一个匿名PL/SQL过程块(例2),也可以是对已创建存储过程的调用(例1)

    2. 行级触发器的话,用户可以用NEW和OLD引用新值和旧值

    3. 如果触发动作体执行失败,则激活触发器的事件(对数据库的增删改查)会终止执行

例1:当对表SC的Grade属性进行修改时,若分数增加了10%,则将此次操作记录到下表中

SC_U(Sno,Cno,Oldgrade,Newgrade)

行级触发器

CREATE TRIGGER SC_T
AFTER UPDATE OF Grade ON SC //当对SC表中Grade列进行修改后才出发下边的
REFERENCING
OLD row AS Oldtuple,//修改之前的数据和修改之后的数据赋予两个变量
NEW row as newtuple
FOR EACH ROW//行级触发器,每次Grade更新都触发下边的语句
WHEN(NewTuple.grade>=1.1*Oldtuple.grade)
    INSERT INTO SC_U
    VALUES(Oldtuple.sno,Oldtuple.cno,Oldtuple.grade,Newtuple.grade)

例2:教授工资不得低于4000,如果低于4000,则自动改为4000

CREATE TRIGGER TEST
BEFORE INSERT OR UPDATE ON teacher_table
REFERENCING NEW row as newtuple
FOR EACHE ROW
BEGIN //PL/SQL过程块
    IF(newtuple.job=='教授')AND(newtuple.sal<4000)
    THEN newtuple:=4000
    END IF;
 END;

5.7.2激活触发器

当数据表中有多个触发器:遵循以下顺序:

  1. BEFORE

  2. SQL语句

  3. AFTER触发器

当有多个相同类型的触发器,遵循谁先创建谁先执行的原则

5.7.3删除触发器

DROP TRIGGER<触发器名><表名>

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇