当前位置:首页 > 问答 > 正文

sql server里怎么搞外键约束的加和删,步骤啥的简单说说

整理自微软官方文档“SQL Server 文档 - CREATE TABLE 和 ALTER TABLE”部分,以及一些常见的数据库管理实践)

在 SQL Server 里,外键约束就像是给两个表之间拉了一条线,规定了一个表里的数据必须和另一个表里的数据对得上号,你有一个“订单”表,里面有个“客户ID”字段,这个字段的值就不能胡编乱造,必须在你另一个“客户”表里确实存在这么个客户ID,搞这个约束的目的就是为了保证数据别乱套,保持什么“引用完整性”,下面我就简单说说怎么加和删这个东西。

第一部分:怎么加外键约束

加外键约束,基本上有两种情况:一个是在你刚开始创建新表的时候顺手就给它加上;另一个是表已经存在了,后来再给它添上去。

创建新表时加外键

当你用 CREATE TABLE 语句建一个新表的时候,你可以在定义列的时候或者在所有列都定义完了之后,来指定外键约束,放在后面一起定义会更清楚点。

举个例子,假设我们有两个表:一个是“部门”表(主表),一个是“员工”表(从表),员工应该属于某个存在的部门。

我们得先有主表,或者同时创建,这里我们先创建“部门”表:

CREATE TABLE 部门 (
    部门ID INT PRIMARY KEY IDENTITY(1,1), -- 主键,自己增长
    部门名称 NVARCHAR(50) NOT NULL
);

创建“员工”表,并加上外键约束:

CREATE TABLE 员工 (
    员工ID INT PRIMARY KEY IDENTITY(1,1),
    姓名 NVARCHAR(50) NOT NULL,
    部门ID INT, -- 这个字段将指向“部门”表的主键
    CONSTRAINT FK_员工_部门 -- 这里给外键约束起个名字,FK_员工_部门
        FOREIGN KEY (部门ID) -- 指定当前表的哪个字段是外键
        REFERENCES 部门(部门ID) -- 指定外键引用的是哪个表(主表)的哪个字段(主键)
);

解释一下上面的代码:

  • CONSTRAINT FK_员工_部门CONSTRAINT 关键字表示要定义一个约束,FK_员工_部门 是你给这个外键约束起的名字,起个好记的名字很重要,以后要删除或者管理的时候方便,通常用 FK_ 开头,后面跟着从表名和主表名。
  • FOREIGN KEY (部门ID)FOREIGN KEY 关键字说明要定义外键,括号里的 部门ID 是“员工”表里的那个字段,它要受到约束。
  • REFERENCES 部门(部门ID)REFERENCES 关键字指定这个外键指向哪里。部门 是主表的名称,部门ID 是主表里的主键字段。

这样,外键约束就加好了,以后你要是往“员工”表里插入数据,部门ID 这个字段的值要么是 NULL(如果允许为空的话),要么就必须在“部门”表的“部门ID”字段里能找到这个值,否则 SQL Server 就会报错,不让你插。

给已经存在的表加外键

员工”表已经创建好了,但一开始忘了加外键,可以用 ALTER TABLE 语句来后加上去,假设“员工”表已经存在,并且有“部门ID”字段,但还没有外键约束。

语法大概是这样的:

ALTER TABLE 员工 -- 指定要修改的表是“员工”
ADD CONSTRAINT FK_员工_部门 -- 添加一个约束,名字叫 FK_员工_部门
    FOREIGN KEY (部门ID) -- 指定外键字段
    REFERENCES 部门(部门ID); -- 指定引用的主表和主键

在执行这个操作之前,有件事要特别注意(来源自常见实践提醒):你必须确保现在“员工”表里已有的所有“部门ID”数据,都能在“部门”表里找到对应的“部门ID”,如果已经有数据不对应,员工”表里有个“部门ID”是 999,但“部门”表里根本没有 ID 为 999 的部门,SQL Server 就会拒绝添加这个外键约束,会报错,你得先把这些“脏数据”清理掉或者修正过来,才能成功加上外键。

关于外键约束的一些可选设置

在加外键的时候,你还可以规定一些额外的行为,主要是针对当主表里的数据被更新(UPDATE)或删除(DELETE)时,从表应该怎么办,这是在 REFERENCES 子句后面用 ON UPDATEON DELETE 来设置的,常见的选项有:

  • NO ACTION:这个是默认值,意思是如果主表的某行被更新或删除时,会导致从表有数据对应不上(即违反外键约束),那么就不允许进行这个更新或删除操作,你想删除“部门”表里的一个部门,但如果“员工”表里还有员工属于这个部门,删除就会失败。
  • CASCADE:级联操作,如果主表的数据变了,从表里对应的数据也跟着自动变。
    • ON DELETE CASCADE:如果主表的一行被删除,那么从表里所有引用了这行主键的数据行也会被自动删除。(警告:这个要非常小心地用,容易误删大量数据!)
    • ON UPDATE CASCADE:如果主表的主键值被更新了,那么从表里所有对应的外键值也会自动更新为新的值。
  • SET NULL:如果主表的行被删除或更新(导致引用失效),那么从表里对应的外键值会被自动设置为 NULL,这要求从表的外键字段允许为 NULL。
  • SET DEFAULT:类似 SET NULL,不过是把从表的外键值设置成该字段定义的默认值。

我们想在删除一个部门时,自动把该部门员工的“部门ID”设为 NULL(假设允许NULL),可以这样加外键:

ALTER TABLE 员工
ADD CONSTRAINT FK_员工_部门
    FOREIGN KEY (部门ID)
    REFERENCES 部门(部门ID)
    ON DELETE SET NULL; -- 当主表数据被删除时,从表外键设NULL

第二部分:怎么删外键约束

删除外键约束比添加简单多了,因为你不需要关心数据问题,你就是要把两个表之间的这条“线”剪断。

删除也需要用 ALTER TABLE 语句,但是是 DROP CONSTRAINT

语法非常简单:

ALTER TABLE 员工 -- 指定要从哪个表删除约束
DROP CONSTRAINT FK_员工_部门; -- DROP CONSTRAINT 后面跟着你当初给外键起的名字

就这么一句,外键约束就删掉了,删掉之后,“员工”表的“部门ID”字段和“部门”表就没有强制关系了,你就可以输入任何值,甚至是不存在的部门ID,数据库也不会拦着你,所以删除外键要谨慎,因为这可能会引入数据不一致的风险。

关键步骤小结:

  1. 加外键(建表时):CREATE TABLE 语句里,用 CONSTRAINT ... FOREIGN KEY ... REFERENCES ... 的语法。
  2. 加外键(修改表时):ALTER TABLE 表名 ADD CONSTRAINT ... FOREIGN KEY ... REFERENCES ...,务必先检查现有数据是否满足引用完整性。
  3. 删外键:ALTER TABLE 表名 DROP CONSTRAINT 外键约束名,需要你知道外键约束的具体名称。

最后提醒一下,你可以通过 SQL Server Management Studio (SSMS) 的图形界面来操作外键,点点鼠标就能完成添加和删除,但了解背后的 SQL 语句还是很有必要的,特别是需要写脚本或者自动化部署的时候,在 SSMS 里,你可以在对象资源管理器中找到对应的表,右键选择“设计”,然后通过右键菜单管理“关系”(即外键);或者是在数据库关系图里拖拽连线。

sql server里怎么搞外键约束的加和删,步骤啥的简单说说