创建外键关系

适用于:SQL Server 2016 (13.x) 及更高版本 Azure SQL 数据库 Azure SQL 托管实例

本文介绍如何使用 SQL Server Management Studio 或 Transact-SQL 在 SQL Server 中创建外键关系。 当希望将一个表的行与另一个表的行相关联时,您可在这两个表之间创建关系。

权限

使用外键创建新表需要在数据库中具有 CREATE TABLE 权限,并对在其中创建表的架构具有 ALTER SCHEMA 权限。

在某一现有表中创建外键需要对该表具有 ALTER TABLE 权限。

限制

  • 外键约束不一定要链接到另一个表中的主键约束。 外键还可以定义为引用另一个表中 UNIQUE 约束的列。

  • 如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用列中存在。 否则,将返回外键冲突错误消息。 要确保验证了组合外键约束的所有值,请对所有参与列指定 NOT NULL

  • FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。 跨数据库的引用完整性必须通过触发器实现。 有关详细信息,请参阅 CREATE TRIGGER (Transact-SQL)

  • FOREIGN KEY 约束可引用同一表中的其他列,并称之为自引用。

  • 在列级指定的 FOREIGN KEY 约束只能列出一个引用列。 此列的数据类型必须与定义约束的列的数据类型相同。

  • 在表级指定的 FOREIGN KEY 约束所具有的引用列数目必须与约束列列表中的列数相同。 每个引用列的数据类型也必须与列表中相应列的数据类型相同。

  • 对于表中可包含的引用其他表的 FOREIGN KEY 约束数量,数据库引擎没有预定义的限制。 数据库引擎也不限制由引用特定表的其他表所拥有的 FOREIGN KEY 约束数量。 但是,使用的 FOREIGN KEY 约束的实际数目受硬件配置以及数据库和应用程序设计的限制。 表最多可以将 253 个其他表和列作为外键引用(传出引用)。 在 SQL Server 2016 (13.x) 及更高版本中,可在单独的表中引用的其他表和列(传入引用)的数量限制已从 253 提高至 1 万。 (兼容性级别至少必须为 130。)数量限制的提高带来了下列约束:

    • DELETEUPDATE DML 操作支持大于 253 个外键引用。 不支持 MERGE 操作。

    • 对自身进行外键引用的表仍只能进行 253 个外键引用。

    • 列存储索引或内存优化表暂不支持进行超过 253 个外键引用。

  • 对于临时表不强制 FOREIGN KEY 约束。

  • 如果在 CLR 用户定义类型的列上定义外键,则该类型的实现必须支持二进制排序。 有关详细信息,请参阅 CLR 用户定义类型

  • 仅当 FOREIGN KEY 约束引用的主键也定义为类型 varchar(max) 时,才能在此约束中使用类型为 varchar(max) 的列。

在表设计器中创建外键关系

使用 SQL Server Management Studio

  1. 在对象资源管理器中,右键单击将位于关系的外键方的表,再选择“设计”

    该表在创建和更新数据库表中打开。

  2. 在“表设计器”菜单上,选择“关系”。 (查看标题中的“表设计器”菜单,或者右键单击表定义的空白区域,然后选择“关系...”。)

  3. 在“外键关系”对话框中,选择“添加”

    “选定的关系”列表中将以系统提供的名称显示关系,格式为 FK_<tablename>_<tablename>,其中第一个 tablename 是外键表的名称,第二个 tablename 是主键表的名称。 这只是外键对象的“(名称)”字段的默认和通用命名约定。

  4. 在“选定的关系”列表中单击该关系

  5. 选择右侧网格中的“表和列规范”,再选择该属性右侧的省略号 (…)

  6. 在“表和列”对话框中,从“主键”下拉列表中选择要位于关系主键方的表。

  7. 在对话框下方的网格中,选择要分配给表的主键的列。 在每列右侧的相临网格单元格中,选择外键表的相应外键列。

    表设计器 将为此关系提供一个建议名称。 若要更改此名称,请编辑 “关系名” 文本框的内容。

  8. 选择 “确定” 以创建该关系。

  9. 关闭表设计器窗口,并保存更改,使外键关系更改生效

在新表中创建外键

使用 Transact-SQL

下面的示例创建一个表,并对列 TempID 定义外键约束,以引用 AdventureWorks 数据库中 Sales.SalesReason 表内的列 SalesReasonIDON DELETE CASCADEON UPDATE CASCADE 子句用于确保对 Sales.SalesReason 表的更改自动传播到 Sales.TempSalesReason 表。

CREATE TABLE Sales.TempSalesReason (
    TempID INT NOT NULL,
    Name NVARCHAR(50),
    CONSTRAINT PK_TempSales
        PRIMARY KEY NONCLUSTERED (TempID),
    CONSTRAINT FK_TempSales_SalesReason FOREIGN KEY (TempID)
        REFERENCES Sales.SalesReason(SalesReasonID)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);

在现有表中创建外键

使用 Transact-SQL

下面的示例对列 TempID 创建外键,并引用 AdventureWorks 数据库中 Sales.SalesReason 表内的列 SalesReasonID

ALTER TABLE Sales.TempSalesReason
ADD CONSTRAINT FK_TempSales_SalesReason FOREIGN KEY (TempID)
REFERENCES Sales.SalesReason (SalesReasonID)
   ON DELETE CASCADE
   ON UPDATE CASCADE;