引用完整性指的是表之间的关系。由于数据库中每一表都必须具有主键,因此此主键可出 现在其他的表中,这是因为它与那些表内数据的关系。当来自一个表的主键出现在另一表 中时,将它称之为外键。
外键连接表并在表之间创建依赖。若干表可形成依赖的层级结构,这样,如果您更改或删 除一个表中的行,则您破坏在其他表中行的含义。例如,下图展示 customer 表 的 customer_num 列是那个表的主键,以及 orders 和 cust_call 表中的外键。 在 orders 和 cust_calls 表中都引用客户编号 106,George Watson™。如果从 customer 表删除 客户 106,则破坏三个表以及此特定的客户之间的链接。
图: 演示数据库中的引用完整性
当您删除包含主键的行,或以不同的主键更新它时,您破坏了包含那个值作为外键的任何 行的含义。引用完整性是外键对主键的逻辑依赖。包含外键的行的完整性依赖于它引用的 那行的完整性—包含相匹配的主键的行。
在缺省情况下,数据库服务器不允许您违反引用完整性,且如果在您从子表删除行之前, 您尝试从父表删除行,则向您提示错误消息。然而,您可使用 ON DELETE CASCADE 选 项来在从父表删除的同时对相应的子表进行删除。请参阅 ON DELETE CASCADE 选项。
要定义主键和外键以及它们之间的关系,请使用 CREATE TABLE 和 ALTER TABLE 语 句。要获取关于这些语句的更多信息,请参阅《GBase 8s SQL 指南:语法》。
ON DELETE CASCADE 选项
当您从主键为表删除行时,要保持引用完整性,请使用 CREATE TABLE 和 ALTER TABLE 语句的 REFERENCES 子句中的 ON DELETE CASCADE 选项。此选项允许您使 用单个删除命令从父表删除一行以及在相匹配的子表中它的对应行。
在级联删除期间锁定
在删除期间,保持父表和子表上的所有符合条件的行上的锁定。当您指定删除时,在执行 任何引用操作之前,执行从父表请求的删除。
多个子表的情况
如果您具有带有两个子约束的父表,一个子表指定了级联删除,另一个子表没有级联删除, 且您尝试从同时应用于两个子表的父表删除一行,则 DELETE 语句失败,且从父表和子表 都不删除行。
必须打开日志记录
为了使级联删除起作用,您必须在您的当前数据库中打开日志记录。在 事务日志记录 中讨 论日志记录和级联删除。
级联删除的示例
假设您有应用了引用完整性规则的两个表,父表 accounts,以及子表 sub_accounts。下列 CREATE TABLE 语句定义引用约束:
CREATE TABLE accounts ( acc_num SERIAL primary key, acc_type INT, acc_descr CHAR(20)); CREATE TABLE sub_accounts ( sub_acc INTEGER primary key, ref_num INTEGER REFERENCES accounts (acc_num) ON DELETE CASCADE, sub_descr CHAR(20));
accounts 表的主键,acc_num 列,使用 SERIAL 数据类型,sub_accounts 表的外键,
ref_num 列,使用 INTEGER 数据类型。允许组合主键上的 SERIAL 与外键上的 INTEGER
数据类型。仅在此条件下,您可混合并匹配数据类型。SERIAL 数据类型是 INTEGER,且 数据库自动地为该列生成值。所有其他主键与外键组合都必须显式地相匹配。例如,定义 为 CHAR 的主键必须与定义为 CHAR 的外键相匹配。 sub_accounts 表的外键的定义,ref_num 列,包括 ON DELETE CASCADE 选项。此选项指 定在父表 accounts 中任何行的删除都将自动地导致删除子表 sub_accounts 的对应行。
要从将级联删除 sub_accounts 表的 accounts 表删除一行,您必须打开日志记录。打开日志 记录之后,您可从两个表都删除账户编号 2,如下例所示:
DELETE FROM accounts WHERE acc_num = 2;




