主键约束跟外键约束的完整性

主键约束和外键约束的完整性

在执行DML语句(例如INSERT、UPDATE或DELETE)时,数据库会确保表中的行都可以维护自身的完整性。这就是说对表中行所做的任何修改都不能影响表的主、外键关系。

8.5.1  主键约束

下面来看几个介绍主键约束的例子。customers表的主键是customer_id列,这意味着customer_id列中保存的每一个值都必须是唯一的。如果试图插入一个与主键列值重复的行,数据库就会返回ORA-00001错误,例如:

主键约束跟外键约束的完整性SQL> INSERT INTO customers (

2     customer_id, first_name, last_name, dob, phone

3   ) VALUES (

4   1, 'Jason', 'Price', '01-JAN-60', '800-555-1211'

5   );

INSERT INTO customers (

*

ERROR at line 1:

ORA-00001: unique constraint (STORE.CUSTOMERS_PK) violated

如果试图将主键值修改为表中已有的一个主键值,数据库也会返回同样的错误:

主键约束跟外键约束的完整性SQL> UPDATE customers

2   SET customer_id = 1

3   WHERE customer_id = 2;

UPDATE customers

*

ERROR at line 1:

ORA-00001: unique constraint (STORE.CUSTOMERS_PK) violated

8.5.2  外键约束

所谓外键关系就是一个表中的列引用了其他表中的列。例如,products表中的product_type_id列引用了product_types表中的product_type_id列。 product_types表称为父表(parent table),而products表则称为子表(child table),这是因为products表中的product_type_id列依赖于product_types表中的product_type_id 列。

如果试图向products表中插入一行,但此行的 product_type_id不存在,数据库就会返回ORA-02291错误。这个错误说明数据库无法找到一个匹配的父键值(此处父键就是 product_types表中的product_type_id列)。在下面这个例子中,就返回这样一个错误,因为product_types表中不存在product_type_id为6的行:

主键约束跟外键约束的完整性SQL> INSERT INTO products (

2     product_id, product_type_id, name, description, price

3   ) VALUES (

4   13, 6, 'Test', 'Test', NULL

5   );

INSERT INTO products (

*

ERROR at line 1:

ORA-02291: integrity constraint (STORE.PRODUCTS_FK_PRODUCT_TYPES)

violated - parent key not found

同理,如果试图将products表中一行的product_type_id列设置为一个不存在的父键值,数据库也会返回相同的错误。例如:

主键约束跟外键约束的完整性SQL> UPDATE products

2   SET product_type_id = 6

3  WHERE product_id = 1;

UPDATE products

*

ERROR at line 1:

ORA-02291: integrity constraint (STORE.PRODUCTS_FK_PRODUCT_TYPES)

violated - parent key not found

如果试图从父表中删除已经有依赖子行的一行,数据库就会返回ORA-02292错误。例如,如果试图删除product_types表中product_type_id列为1的行,数据库就会返回ORA- 02292错误,因为products表中包含了product_type_id列等于1的行:

主键约束跟外键约束的完整性SQL> DELETE FROM product_types

2  WHERE product_type_id = 1;

DELETE FROM product_types

*

ERROR at line 1:

ORA-02292: integrity constraint (STORE.PRODUCTS_FK_PRODUCT_TYPES)

violated - child record found

如果数据库允许执行这个删除操作,那么子行就无效了,因为它们不能指向父表中的有效值了。

 

-----------------------------------------------

PowerDesigner

  参照完整性约束

  限制(Restrict)。不允许进行修改或删除操作。若修改或删除主表的主键时,如果子表中存在子记录,系统将产生一个错误提示。这是缺省的参照完整性设置。

  置空(Set Null)。如果外键列允许为空,若修改或删除主表的主键时,把子表中参照的外键列设置为空值(NULL)。

  置为缺省(Set Default)。如果指定了缺省值,若修改或删除主表的主键时,把子表中参照的外键设置为缺省值(Default)。

  级联(Cascade)。把主表中主键修改为一个新的值时,相应修改子表中外键的值;或者删除主表中主键的记录时,要相应删除子表中外键的记录。