实体完整性
实体完整性要求每一个数据表都必须有主键,而作为主键的所有字段,其属性必须是独一及非空值。
主码的声明:
方法一:单属性列级定义主码
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY, Sname CHAR(20) NOT NULL, Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20) );
方法二:单属性表级定义主码
CREATE TABLE Student( Sno CHAR(9), Sname CHAR(20) NOT NULL, Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20), PRIMARY KEY (Sno) );
方法三:多属性表级定义主码
CREATE TABLE SC( Sno CHAR(9) NOT NULL, Cno CHAR(4) NOT NULL, Grade SMALLINT, PRIMARY KEY (Sno,Cno) /*只能在表级定义主码*/ );
总结:
对于单属性主码可以有两种定义方法:单属性列级主码和单属性表级主码
对于多属性主码只能定义在表级
思考:
一个表可以有多个主码吗?
答:一张表只能有一个主码,不可以有多个主码。所谓的一张表有多个主码,是指的联合主码(用多个字段作为一张表的主键)。
实体完整性检查和违约处理
主要是检查主码是否唯一以及主码是否为空,如果满足上述两种条件之一则拒绝更新。检查的方法是进行全表扫描,这样做的缺点是十分耗时,解决的办法是为主码建立一个索引(使用B树或者B+树来实现)。
参照完整性
又称引用完整性,是数据的属性,用以表明引用之有效。参照完整性不允许关系中又不存在的实体引用。参照完整性与实体完整性二者皆是关系模型必须要满足的完整性约束条件,其目的在于保证数据的一致性。参照完整性是通过外码来实现的,在CREATE TABLE中用FOREIGN KEY短语定义哪些为外码,用REFERENCES短语指明这些外码参照那些表中的主码。
外码的定义
方法一:定义列级参照完整性
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY, /* 列级完整性约束条件,Sno是主码*/ Sname CHAR(20) UNIQUE, Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20) FOREIGN KEY REFERENCES DEPT(Deptno) /*在列级定义参照完整性*/ );
方法二:定义表级参照完整性
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY, /* 列级完整性约束条件,Sno是主码*/ Sname CHAR(20) UNIQUE, Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20), FOREIGN KEY(Sdept) REFERENCES DEPT(Deptno)/*在表级定义参照完整性*/ );
也可以用一个表的主码当做另一个表的外码来使用
CREATE TABLE Course ( Cno VARCHAR(10) PRIMARY KEY, Cname VARCHAR(20), Pcno VARCHAR(20), Credit FLOAT, FOREIGN KEY(Pcno) REFERENCES Course(Cno) )ENGINE=INNODB DEFAULT CHARSET=utf8;
一个表只能够定义一个实体完整性约束但可以定义多个参照完整性约束
CREATE TABLE SC( Sno CHAR(9) NOT NULL, Cno CHAR(4) NOT NULL, Grade SMALLINT, PRIMARY KEY (Sno, Cno), /*在表级定义实体完整性*/ FOREIGN KEY (Sno) REFERENCES Student(Sno), /*在表级定义参照完整性*/ FOREIGN KEY (Cno) REFERENCES Course(Cno) /*在表级定义参照完整性*/ );
参照完整性的违约处理
- 拒绝(NO ACTION)执行:不允许该操作执行。该策略一般设置为默认策略
- 级联(CASCADE)操作:当删除或修改被参照表的一个元组造成了与参照表的不一致,则删除或修改参照表中的所有造成不一致的元组
- 设置为空值(SET-NULL):当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
显示说明参照完整性的违约处理示例
CREATE TABLE SC1( Sno CHAR(10) NOT NULL, Cno CHAR(4) NOT NULL, Grade SMALLINT, PRIMARY KEY(Sno,Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno) ON DELETE CASCADE /*级联删除SC表中相应的元组*/ ON UPDATE CASCADE, /*级联更新SC表中相应的元组*/ FOREIGN KEY (Cno) REFERENCES Course(Cno) ON DELETE NO ACTION /*当删除course 表中的元组造成了与SC表不一致时拒绝删除*/ ON UPDATE CASCADE /*当更新course表中的cno时,级联更新SC表中相应的元组*/ );
用户定义完整性
用户自定义完整性指针对某一具体关系数据库的约束条件,他反应某一具体应用所涉及的数据必须满足的语义要求。例如,某个属性必须取值唯一,某个非主属性也不能够取空值,某个属性的取值范围在0-100之间。
属性上的用户定义完整性
定义方法:NOT NULL(非空), UNIQUE(唯一), CHECK(检查是否满足某个表达式)
特点:只涉及单个属性
检查时机:插入元祖或者修改属性的值时
违约处理:拒绝执行
举个例子:
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY, Sname CHAR(8) UNIQUE NOT NULL, /*唯一且非空*/ Ssex CHAR(2) CHECK (Ssex IN (‘男’,’女’)), /*性别属性Ssex只允许取'男'或'女' */ Sage SMALLINT, Sdept CHAR(20) );
元组上的用户定义完整性
定义方法:在CREATE TABLE时可以用CHECK子句定义元祖上的约束条件
特点:可以设置不同属性之间的取值的相互约束条件
检查时机:插入或修改属性的值时
违约处理:拒绝执行
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY, Sname CHAR(8) UNIQUE NOT NULL, /*唯一且非空*/ Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20), CHECK (Ssex=’女’ OR Sname NOT LIKE 'Ms.%') /*定义了元组中Sname和Ssex两个属性值之间的约束条件*/ );
完整性约束命名子句
用法
CONSTRAINT <完整性约束条件名><完整性约束条件>
<完整性约束条件>包括NOT NULL, UNIQUE, PRIMARY KEY短语,FOREIGN KEY短语,CHECK短语等。
举个栗子
CREATE TABLE Student( Sno NUMERC(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语句进行修改
/*删除完整性约束*/
ALTER TABLE Student DROP CONSTRAINT C4;
/*增添完整性约束*/
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999);
课后习题
假设有下面两个关系:
职工(职工号,姓名,年龄,职务,工资,部门号),其中职工号为主码;
部门(部门号,名称,经理名,电话),其中部门号为主码。
用SQL语言定义这两个关系,要求在模式中完成以下完整性约束条件的定义:
(1)定义每个关系的主码;(2)定义参照完整性;(3)定义职工年龄不得超过60岁。
SQL:
CREATE TABLE Dept( Deptno char(20) PRIMARY KEY, Dname char(50) UNIQUE, Dmanager char(20) NOT NULL, Phone char(20) NOT NULL ); create table Staff( Sno char(20) primary key, Sname char(20) unique, Sage NUMERIC(3), Spost char(20) not null, Swage smallint, SDept char(20), foreign key (Sdept) references Dept(Deptno), CONSTRAINT C1 CHECK (Sage <= 60) );
运行结果:
从上图中的结果中我们可以看出因为年龄不满足约束条件C1所以插入失败
当我们修改年龄之后便可以成功插入
之前在验证PPT上的例子的时候一直报错
check the manual that corresponds to your MySQL server version for the right syntax to use near
经过查阅资料发现得知可能是自己MySQL的版本的问题,于是就从装了一下MySQL,然后就可以正常的使用了。
参考:
https://blog.csdn.net/qq_42900286/article/details/106108616