当前位置: 首页 > news >正文

【数据库】数据库的完整性

数据库完整性包含正确性、有效性和相容性,主要是为了防范不合语义的、不正确的数据。

这种完整性约束条件分成几类。按照约束条件对象关系,区分为关系-元组间的约束、元组-元组间的约束和列-字段的约束;按照约束的状态,可以分成静态条件(某个确定状态时数据的约束条件)和动态(从一个状态到另一个状态的新旧值约束条件)条件。

DBMS需要完成:

  1. 定义完整性约束条件机制
  2. 提供完整性检查的方法
  3. 违约处理

通过这样的机制,就可以保证数据库完整性。

实体完整性

对于关系模型,使用PRIMARY KEY来定义实体完整性。实体完整性要求主码不能取空。对于单属性构成的码,可以定义为列级,也可以定义为表级;多个属性构成的码只能有一种说明方法。

CREATE TABLE S {Sno CHAR(9) PRIMARY KEY, /*列级定义主码*/...
}
CREATE TABLE S {Sno CHAR(9), ...PRIMARY KEY(Sno) /*表级定义主码*/
}

对于插入和更新操作,要检查主码是否唯一,并且每个属性不为空。

参照完整性

CREATE TABLE SC (Sno CHAR(9) NOT NULL,Cno CHAR(4) NOT NULL,Grade SMALLINTPRIMARY KEY (Sno, Cno)/*在表级定义实体完整性*/FOREIGN KEY (Sno) REFERENCES Student(Sno)/*在表级定义参照完整性*/FOREIGN KEY (Cno) REFERENCES Course(Cno)/*在表级定义参照完整性*/
);

对于参照完整性的违约,情况如下:

被参照表参照表违约处理
可能破坏参照完整性插入元组拒绝
可能破坏参照完整性修改外码值拒绝
删除元组可能破坏参照完整性拒绝/级联删除/设置为空
修改主码值可能破坏参照完整性拒绝/级联修改/设置为空

如果设置为空,还需要设置外码列是否为空。对于其设置可以使用这样的方法:

FOREIGN KEY (Sno) REFERENCES Student(Sno) ON DELETE CASCADE /*级联删除SC表中相应的元组*/ON UPDATE SET NULL/*级联更新SC表中相应的元组*/
FOREIGN KEY (Cno) REFERENCES Course(Cno) ON DELETE NO ACTION /*当删除course 表中的元组造成了与SC表不一致时拒绝删除*/ON UPDATE CASCADE  /*当更新course表中的cno时,级联更新SC表中相应的元组*/

用户自定义完整性

一、属性级别的约束条件

对于属性级别,分成三种:

  • NOT NULL
  • UNIQUE
  • CHECK

下面进行举例。

NOT NULL:

CREATE TABLE SC (Sno CHAR(9) NOT NULL,Cno CHAR(4) NOT NULL,Grade SMALLINT NOT NULL
)

UNIQUE:

CREATE TABLE DEPT(Deptno NUMERIC(2),Dname CHAR(9) UNIQUE
)

CHECK:

CREATE TABLE Student (Sno CHAR(9) PRIMARY KEY,Ssex CHAR(2) CHECK (SSex IN ('男','女'))
)

如果约束不满足则会拒绝执行。

二、元组级别的约束条件

使用CHECK。

CREATE TABLE Student (Sno CHAR(9) PRIMARY KEY,Sname CHAR(8) NOT NULL,SSex CHAR(2) CHECK (SSex IN ('男','女')),CHECK(SSex = '女' OR Sname NOT LIKE 'Ms.%')/*男性不能以Ms.打头*/
)

如果约束不满足则会拒绝执行。

三、约束子句

使用CONSTRAINT进行约束。

CONSTRAINT <约束名> [PRIMARY KEY 短语|FOREIGN KEY 短语|CHECK 短语
]

比如建立Student表,要求学号在90000-99999之间,姓名不能取空,年龄小于30,性别为男或女。

CREATE TABLE Student(Sno NUMERIC(6)CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),Sname CHAR(20)CONSTRAINt C2 NOT NULL,Sage NUMERIC(3)CONSTRAINT C3 CHECK(Sage < 30),Ssex CHAR(2)CONSTRAINT C4 CHECK(SSex IN('男','女')),CONSTRAINT StudentKey PRIMARY KEY(Sno)
)

如果需要修改完整性限制,使用ALTER TABLE语句

比如把之前的SSex进行修改:

ALTER TABLE Student
DROP CONSTRAINT C4;
ALTER TABLE Student
CONSTRAINT C4 CHECK(SSex IN('男','女','其它'))

四、域的完整性约束

可以创建一个域进行取值贤治。

CREATE DOMAIN GenderDomain VARCHAR(2)
CHECK(VALUE IN('男','女','其它'))

这个时候,对SSex说明可以直接使用SSex GenderDomain

也可以对其域进行一定的修改:

/*建立*/
CREATE DOMAIN GenderDomain CHAR(2)
CONSTRAINT GD CHECK(VALUE IN('男','女'));
/*删除*/
ALTER DOMAIN GenderDomain
DROP CONSTRAINT GD;
/*增加*/
ALTER DOMAIN GenderDomain
ADD CONSTRAINT GDD CHECK(VALUE IN('1', '0'))

触发器

触发器是用户顶i有的一类事件驱动的特殊过程,由服务器自动激活。对触发器的定义使用下面的形式:

CREATE TRIGGER <触发器名>{BEFORE|AFTER} <触发事件(INSERT|DELETE|UPDATE)> ON <表名>FOR EACH {ROW | STATEMENT}[WHEN <触发条件>]<触发动作体>

事实上,可以用五元组 ( D , O , A , C , P ) (D,O,A,C,P) (D,O,A,C,P)来表示一个完整性规则,其中

  • D:数据
  • O:触发完整性约束的操作
  • A:约束条件
  • C:选择数据对象值的谓词
  • P:违反完整性约束时出发的处理

这里要注意的是,触发器类型可以分成行级(ROW)或者语句级(STATEMENT)。比如下面的语句

UPDATE Teacher SET Deptno = 5

那么语句级触发级只执行一次,行级有多少行就执行多少次。

考虑下面的例子:一个BEFORE行级触发器,让Teacher定义规则:教授工资不得低于4000,低于就自动改成4000.这个时候,可以使用下面的语句:

CREATE TRIGGER Insert_Or_Update_SalBEFORE INSERT OR UPDATE ON TeacherFOR EACH ROWAS BEGINIF (new.Jpb = '教授') AND (new.Sal < 4000) THENnew.sal := 4000;END IF;END;

再看一个例子。我们试图实现在教师表的工资变化的时候自动在工资变化表Sal_log增加相应记录。为此,先建立Sal_log表

CREATE TABLE Sal_log(Eno NUMERIC(4) references teacher(eno),Sal NUMERIC(7,2),Username CHAR(10),Date TIMESTAMP
);

然后定义触发器

CREATE TRIGGER Insert_SalAFTER INSERT ON TeacherFOR EACH ROWAS BEGININSERT INTO Sal_log VALUES(new.Eno, new.Sal, CURRENT_USER, CURRENT_TIMESTAMP;);END;
CREATE TRIGGER Update_SalAFTER UPDATE ON TeacherFOR EACH ROWAS BEGINIF (new.Sal <> old.sal) THEN INSERT INTO Sal_log VALUES(new.Eno, new.Sal, CURRENT_USER, CURRENT_TIMESTAMP;);END IF;END;

触发器是自动激活的,一般遵循BEFORE触发器-SQL语句-AFTER触发器的执行顺序。

删除触发器使用DROP语句:

DROP TRIGGER <触发器名> ON <表名>
http://www.xdnf.cn/news/719803.html

相关文章:

  • 2024 吉林 CCPC
  • 【25-cv-05855】Keith律所代理Paula Alejandra Navarro 版权图
  • RAG技术:私有大模型知识更新的最佳实践
  • 简述如果要存储用户的密码散列,应该使用什么字段进行存储?
  • 数据的类型——认识你的数据
  • SpringBoot使用MQTT协议简述
  • database disk image is malformed 的解决方法
  • C++ —(详述c++特性)
  • 行锁与表锁详解:原理、区别与面试要点
  • 63、【OS】【Nuttx】任务休眠与唤醒:sleep
  • 系统提示词:Google Stitch
  • 【笔记】suna部署之获取 Daytona API key 及 Daytona Sandbox 设置
  • 在力扣刷题中触摸算法的温度
  • Codeforces Round 1024 (Div. 2)
  • 山东省申报高级职称、正高级职称条件(工业、信息化方向)
  • 大数据如何赋能市场情报分析?——精准决策,从数据开始
  • echarts主题切换实现
  • 多模态融合新方向:光学+AI如何智能分拣,提升塑料回收率?
  • 基于卫星遥感数据识别互花米草及原生植被分布及生长的技术原理、关键方法
  • 利用TOA与最小二乘法直接求解
  • React从基础入门到高级实战:React 生态与工具 - React 国际化(i18n)
  • [学习]C++ 模板探讨(代码示例)
  • Python模块中__all__变量失效问题深度解析
  • 虚幻基础:模型
  • 鲜羊奶对青少年心理健康的 “技术向” 营养支持
  • day31 5月29日
  • python打卡第36天
  • WPF中自定义消息弹窗
  • 小白畅通Linux之旅-----Linux安全管理
  • Ubuntu系统下Docker部署Dify保姆级教程:实现内网穿透远程访问