VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

外键

外键约束指定列(或列组)中的值必须与另一个表的某行中出现的值匹配。这维持了两个相关表之间的引用完整性。

假设已经创建一个产品表:

vastbase=# CREATE TABLE products (  product_no integer PRIMARY KEY,  name text,   price numeric ); 

再假设还有一个存储这些产品订单的表。我们希望确保订单表仅包含实际存在的产品订单。所以我们在orders表中定义了一个引用products表的外键约束:

vastbase=# CREATE TABLE orders (  order_id integer PRIMARY KEY,  product_no integer REFERENCES products (product_no),  quantity integer ); 

如果没有创建products表,那么无法创建orders表。

我们说在这种情况下,orders表是引用表,products表是被引用表。同样,有引用和引用列。

上述命令可以缩短为:

vastbase=# CREATE TABLE orders (  order_id integer PRIMARY KEY,  product_no integer REFERENCES products,     quantity integer ); 

因为在没有列列表的情况下,引用表的主键用作引用列。

外键还可以约束和引用一组列。像往常一样,它需要以表约束形式编写。

这是一个人为的语法示例:

vastbase=# CREATE TABLE t1 ( a integer PRIMARY KEY,   b integer,   c integer,   FOREIGN KEY (b, c) REFERENCES other_table (c1, c2) ); 

当然,受约束列的数量和类型需要与引用列的数量和类型相匹配。

可以为外键约束指定自己的名称。

一个表可以有多个外键约束。这用于实现表之间的多对多关系。假设有关于产品和订单的表格,但现在希望允许一个订单包含可能的许多产品(上述结构不允许)。那么可以使用此表结构:

vastbase=# CREATE TABLE products (  product_no integer PRIMARY KEY,  name text,  price numeric );  vastbase=# CREATE TABLE orders ( order_id integer PRIMARY KEY, shipping_address text,     ... );  vastbase=# CREATE TABLE order_items (product_no integer REFERENCES products,  order_id integer REFERENCES orders,   quantity integer,    PRIMARY KEY (product_no, order_id) ); 

请注意,主键与最后一个表中的外键重叠。

我们知道外键不允许创建与任何产品无关的订单。如果在创建引用它的订单后删除了产品,SQL支持处理它。

为了说明这一点,让我们在上面的多对多关系示例中实现以下策略:当有人想要删除仍然被订单引用的产品时(通过 order_items ),我们不允许它。如果有人删除了订单,订单商品也会被删除:

vastbase=# CREATE TABLE products (     product_no integer PRIMARY KEY,     name text,     price numeric );  CREATE TABLE orders (     order_id integer PRIMARY KEY,     shipping_address text,     ... );  CREATE TABLE order_items (     product_no integer REFERENCES products ON DELETE RESTRICT,     order_id integer REFERENCES orders ON DELETE CASCADE,     quantity integer,     PRIMARY KEY (product_no, order_id) ); 

限制和级联删除是两种最常见的选项。 RESTRICT 防止删除引用的行。 NO ACTION表示如果在检查约束时仍存在任何引用行,则会引发错误;如果您未指定任何内容,则这是默认行为。(这两个选项之间的本质区别在于 NO ACTION 允许将检查推迟到事务的后期,而 RESTRICT 则不会。) CASCADE 指定当删除引用的行时,引用它的行应自动删除为好。还有另外两个选项: SET NULL 和 SET DEFAULT。当删除引用的行时,这些引用将引用行中的引用列分别设置为空值或其默认值。请注意,这些不能免除您观察任何约束。例如,如果操作指定SET DEFAULT 但默认值不满足外键约束,则操作将失败。

类似于 ON DELETE ,还有 ON UPDATE,当引用的列被更改(更新)时会调用它。可能的行动是相同的。在这种情况下,CASCADE 表示应将引用列的更新值复制到引用行中。

通常,如果引用行的任何引用列为空,则引用行不必满足外键约束。如果将 MATCH FULL 添加到外键声明中,则仅当所有引用列都为空时,引用行才会转义满足约束(因此,保证空值和非空值的混合使 MATCH FULL 约束失败)。如果您不希望引用行以避免满足外键约束,请将引用列声明为 NOT NULL 。

外键必须引用作为主键或形成唯一约束的列。这意味着引用的列总是有索引(主键或唯一约束下面的索引);因此,检查引用行是否匹配将是有效的。由于引用表中的行的 DELETE 或引用列的 UPDATE 将需要扫描引用表以查找与旧值匹配的行,因此通常也应该对引用列 Build索引。因为并不总是需要这个,并且有很多关于如何索引的选择,所以外键约束的声明不会自动在引用列上创建索引。

另请参阅 CREATE TABLE 的参考文档中的外键约束语法的说明。