数据库之超详细的完整性约束

数据库之超详细的完整性约束

 数据库的完整性是指数据的正确性和相容性。数据库是否具备完整性关系到数据库系统能否真
实地反映现实世界,因此维护数据库的完整性是非常重要的。
 数据库的完整性可分为实体完整性、参照完整性和用户定义的完整性

 

 1.实体完整性

 

       实体完整性是基于主码的一个主码由一个或多个属性组成。实体完整性要求主码中的任一属性(列)不能为空,所谓空值是"不知道"或"无意义"的值。之所以要保证实体完整性主要是因为在关系中,每一个元组的区分是依据主码值的不同,若主码值取空值,则不能标明该元组的存在。
  

2.参照完整性


  参照完整性是基于外码的,若基本关系R中含有与另一基本关系S的主码PK相对应的属性组FK(FK称为R的外码),则参照完整性要求,对R中的每个元组在FK上的值必须是S中某个元组的PK值,或者为空值。
  参照完整性的合理性在于,R中的外码只能对S中主码的引用,不能是S中主码没有的值。

       如学生和选课表两关系,选课表中的学号是外码,它是学生表的主键,若选课表中出现了某个学生表中没有的学号,即某个学生还没有注册,却已有了选课记录,这显然是不合理的。

 对于参照完整性,需要明确以下问题:
 (1)外码能否接受空值问题根据实际应用决定。
 (2)在被参照关系中删除元组的问题。

       级联删除:将参照关系中所有外码值与被参照关系中要删除元组主码值相同的元组一起删除。如果参照关系同时又是另一个关系的被参照关系,则这种删除操作会继续级联下去。
  受限删除(一般系统默认):仅当参照关系中没有任何元组的外码值与被参照关系中要删除元组的主码值相同时,系统才可以执行删除操作,否则拒绝执行删除操作。
  置空删除:删除被参照关系的元组时,并将参照关系中相应元组的外码值置为空值。

    (3)在参照关系中插入元组的问题。


  受限插入:仅当被参照关系中存在相应的元组时,其主码值与参照关系插入元组的外码值相同时,系统才执行插入操作,否则拒绝此操作。
  递归插入:首先向被参照关系中插入相应的元组,其主码值等于参照关系插入元组的外码值,然后向参照关系插入元组。

 

3.用户定义的完整性


  实体完整性和参照完整性适用于任何关系数据库系统。除此之外,不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性就是针对某一具体关系数据库的约束条件,它反映某一具体应用所涉及的数据必须满足的语义要求。
  如果在一条语句执行完后立即检查,则称立即执行约束如果在整个事务执行结束后再进行检查,则称延迟执行约束

4.触发器


  触发器(Trigger)是在关系数据库管理系统中应用得比较多的一种完整性保护措施。触发器的功能一般比完整性约束要强得多。一般而言,在完整性约束功能中,当系统检查出数据中有违反完整性约束条件时,则仅给出必要提示以通知用户,仅此而已。而触发器的功能则不仅仅起提示作用它还会引起系统内自动进行某些操作以消除违反完整性约束条件所引起的负面影响
  在目前数据库中事件一般表示为数据的插入、修改、删除等操作。触发器除了有完整性保护功能外,还有安全性保护功能。

 

5.非空约束


  非空是个规则,是对声明了非空约束的字段限制其取值域不能为空。它不允许在对一列的数据插入或更新时取NULL值。在默认情况下,是所有的列都允许填充NULL值的,只有在列声明了NOTNULL的列值或其他已经包含了NOT NULL约束的列值时,系统强制要求任何时候都不能填充NULL值。非空约束通常会包含在相关的其他约束上,如:主键约束,候选键约束等。因为索引是不对NULL值进行存储的,所以,如果希望使用索引进行表数据的查询,那么必须尽量地使某个要索引的列不包含NULL值。例如:下面语句对emp表的ename字段声明了非空约束。

 

 create table emp (
  ename varchar(32) not null,
  emanager varchar(30)
  );

 对于表emp,如果已经有了数据,而且ename列中已存在NULL值,则该操作将被禁止。只要将空值替换或将对应的行删除,该语句还是可以被允许的。当然对于不明确的列但又不能为空时,可以使用默认值(default)对列值做默认处理,这样也可以远离NULL值对列的影响。

 

 6.CHECK约束


  相对于非空约束,CHECK约束能更灵活地限制某字段取值的值域,客观地说,非空约束是CHECK约束的一个特例而已。CHECK约束需要设计一个表达式,某条记录的某(些)字段的值,如果使这个表达式为假,则这条记录被禁止,反之,则被允许。如果定义一个CHECK约束设计一个某字段不为空的表达式,那么效果就跟非空约束一样了。CHECK约束设计的表达式具体应用到某条将要进行操作的记录的某(些)字段时,只有三个值--true、false、unknown,表达式值为false时将要进行的操作被禁止,其他的则允许。在CHECK约束的表达式中,有如下要求:

 

    (1)该表达式在使用数据插入或更新操作的值时,必须是可以作出逻辑判断的表达式。
    (2)该表达式不可以使用嵌套查询和序列器。
    (3)该表达式不可以使用SQL函数。
    (4)该表达式不可以使用自定义函数。
    (5)该表达式不可以使用DBMS的伪字段(比如Oracle中的rownum、level等)。

下面语句说明如何在创建表的语句中声明CHECK约束。
 

 CREATE TABLE Dept_tab (
  Deptno NUMBER(3),
  Dname VARCHAR2(15),
  Loc VARCHAR2(15),
  CONSTRAINT Loc_check1 CHECK (loc IN ('北京', '上海', '广州'))
  );

该语句为表Dept_tab中的Loc字段声明了名为Loc_check1的CHECK约束,这个约束要求Loc字段只能填写('北京', '上海', '广州')值中的一个,否则,操作将被禁止。

 

7.主键约束


  主键是能唯一标识元组的最小属性集,并且是在数据库中被标记为PRIMARY KEY的属性集。如果某个表的某(些)字段声明为主键,那么这些字段就接受了要遵守如下两条规则。
  (1)在这些作为主键的字段中任何字段任何行都不能为空。
  (2)在这些作为主键的字段中任何两行之间的组合取值不能重复。
  下面语句是在创建表的语句中声明了主键约束。
 

 CREATE TABLE dept (
  deptno NUMBER PRIMARY KEY,
  dname VARCHAR2 (30)
  );

 该语句在表dept中声明了字段deptno为该表的主键,这个主键约束并未命名,它的名称可以由系统自动产生。再看下面的语句:

 CREATE TABLE emp (
  empno NUMBER,
  ename VARCHAR2 (30),
  CONSTRAINT epk PRIMARY KEY (empno)
  );

该语句在表emp中声明了字段empno为主键,同时命名该主键约束为epk.

 

8.候选键约束


  能唯一标识元组的最小属性集,但在数据库中未被标记为PRIMARY KEY,这样的属性集我们称为候选键。这里的候选键实质就是唯一性约束。它的规则要求与主键的规则要求一样,只是未被声明为主键而已。标准SQL并没有直接定义候选键,候选键取值不能为空和不取重复值的约束可以通过UNIQUE NOT NULL来实现,也可以通过UNIQUE KEY来实现。具体要根据不同的DBMS而定。下列语句在创建表中声明了候选键约束。

CREATE TABLE emp (
  empno NUMBER,
  ename VARCHAR2 (30),
  CONSTRAINT euk UNIQUE KEY (empno)
  );

该语句为表emp的empno字段声明了一个叫euk的唯一性约束。

 

5.外键约束


  外键是指在关系模式R中作为候选键的属性集,但在关系模式T中不是候选键。则对于T来说,这些属性集称为相对于R的外键。通常外键在数据库中会被标记为FOREIGN KEY字样。在这里,称R为父模式,T为子模式。通俗地说就是父表中的主键字段被子表中某个字段引用,那么子表的这个字段,则应声明为外键,而父表的那个字段可以声明为主键也可以声明为唯一键(候选键)。一旦子表的字段被声明为父表的外键,同样的一个字段在父表中我们称为引用的父键,在子表中称为引用的子键。子键的取值应遵守如下规则,否则将被禁止。

(1)每个子键的取值不能取父键中取值以外的值,但空除外。
(2)对于父键是组合字段的,子键也应是组合字段,父键要求能唯一地标识父表的每一条记
录,而子键不要求能唯一标识子表的每一条记录。
(3)对于组合键,子键为空时,所有的键的成员字段都为空,不允许部分为空。

 一个子表可以有多个子键,每个子键可以对应不同父表的父键。如果是组合键,那么,同一个字段可能作为不同的外键的成员。当然,子表和父表是相对的,子表如果有唯一键被其他表引用,那么这时的子表对于其他表关于某键,它又是父表。外键的引入,主要是为了表示表间的一对多问题。下面的语句说明了两个表间的外键引用情况。

   CREATE TABLE dept (
  deptno NUMBER PRIMARY KEY,
  dname VARCHAR2 (30)
  );
   CREATE TABLE emp (
  empno NUMBER,
  ename VARCHAR2 (30),
  deptno NUMBER REFERENCES (dept),
  CONSTRAINT efk FOREIGN KEY (deptno) REFERENCES (dept.deptno)
  );

       这两条语句创建了dept和emp两个表,其中dept表中的deptno是它的主键,它被表emp引用,在emp中也有个同样名字的deptno字段,这个字段被声明为引用dept.deptno字段的外键。那么dept表是父表,deptno构成了引用中父表的父键,emp表是子表,deptno构成了引用中子表的子键。

       因为外键是引用父表父键的子表的子键,所以父表的数据是引用的基础。一旦父表数据被修改或删除,引用也会造成相关的影响,表现在子表和子键上,这就需要做出相应的规则来约定父表父键发生改动后子表子键如何来进行维护活动。根据这种活动,我们将子表的外键分为3大类。

       (1)禁止更新和删除父键,许多DBMS默认为这一类外键约束。一旦父表的父键被某个子表的子键引用了,那么父表中已有的数据是禁止修改和删除的。
  (2)删除或更新父表数据的同时删除或更新子表子键中对应父键取值的行
  (3)删除或更新父表数据的同时将子表中对应父键的子键的取值设置为NULL.

 加入这3种外键约束声明的语句可以如下所示:
  

   CREATE TABLE Emp_tab (
  FOREIGN KEY (Deptno) REFERENCES Dept_tab
  );
  该语句说明外键deptno默认为第一类。
  CREATE TABLE Emp_tab (
  FOREIGN KEY (Deptno) REFERENCES Dept_tab ON DELETE CASCADE
  );
  该语句声明一个第二类的外键。
  CREATE TABLE Emp_tab (
  FOREIGN KEY (Deptno) REFERENCES Dept_tab ON DELETE SET NULL
  );
  该语句声明一个第三类的外键。

 

你可能感兴趣的:(软件设计知识点之操作系统)