简体   繁体   English

SQL Server中的外键

[英]Foreign key in SQL Server

I want to know the use of foreign key in SQL Server as I had a debate with one of my colleagues. 我想和一位同事辩论时,知道SQL Server中使用外键。

I have the opinion, when two tables are connected via a foreign key, when the records are deleted from the parent table then the same reference record from the child table should also get deleted. 我认为,当通过外键连接两个表时,从父表中删除记录时,子表中的相同参考记录也应删除。

Say for example I have two tables, Table1 and Table2. 例如,我有两个表,表1和表2。 Table1 has one record with id = 1 and Table2 has two records with id = 1. Table2 is a child table and connected with Table1 via a foreign key. Table1有一个ID为1的记录,而Table2有两个ID为1的记录。Table2是一个子表,并通过外键与Table1连接。 Now when I try to delete the id = 1 record from Table1 then id = 1 (2 records) should be deleted from Table2 at the same time. 现在,当我尝试从Table1删除id = 1记录时,则应同时从Table2中删除id = 1(2条记录)。

He says that's wrong. 他说错了。 In case of a foreign key, I have to separately delete records from both the tables. 如果是外键,我必须分别从两个表中删除记录。

Who is correct? 谁是正确的?

Both answers can be used and can work. 这两个答案都可以使用并且可以起作用。

Your colleague's version puts more responsability on your application (or your DBA) doing the deletion: the app (or DBA) will have to check for child rows first and delete them, and then delete the parent row. 同事的版本使您执行删除的应用程序(或DBA)承担更多责任:应用程序(或DBA)必须先检查子行并删除它们,然后再删除父行。 This works, and doesn't give you any unexpected surprises. 这行得通,并且不会给您带来任何意外的惊喜。

If you put a ON DELETE CASCADE option on your foreign key constraint (which should be possible in just about any serious relational database system), then the behavior would be the way you describe it - that might make sense, from a business point of view (eg delete all order items for an order), but in other cases, it might totally make no sense at all (eg if you delete an order no. 1234, you typically don't want to delete all the products the order items for that order will probably reference). 如果在外键约束上放置一个ON DELETE CASCADE选项(几乎在任何严肃的关系数据库系统中都应该是可能的),那么行为将是您描述它的方式-从业务角度来看这可能是有道理的(例如,删除订单的所有订单商品),但在其他情况下,这可能根本没有意义(例如,如果删除编号为1234的订单,则通常希望删除订单商品所针对的所有商品该命令可能会参考)。

So there are two scenarios - both make sense in certain scenarios, and not such much in others. 因此,存在两种情况-两者在某些情况下有意义,而在其他情况下则没有太大意义。 It's not a simple "either - or" / "right vs. wrong" question at all. 这根本不是一个简单的“要么-要么” /“对与错”问题。

It depends on how things are defined. 这取决于事物的定义方式。 You can either have a cascading delete , or having it blocked (where you have to delete first the one, then the other) 您可以级联删除 ,也可以阻止它(必须先删除一个,然后删除另一个)

You are both right. 你们都是对的。

If cascade delete is enabled then the foreign key rows will also be deleted when the primary key row is deleted. 如果启用了级联删除,那么在删除主键行时,外键行也将被删除。

You can have the tables created to delete in Cascade. 您可以在Cascade中创建要删除的表。 When you add the foreign key constraint you need to specify the contraint 添加外键约束时,需要指定约束

CONSTRAINT fk1
FOREIGN KEY(col) REFERENCES parent(col) ON DELETE CASCADE,

Otherwise, yes, you have to delete children first. 否则,是的,您必须先删除子级。

It depends on if you have an ON DELETE CASCADE or an ON DELETE SET NULL on your TABLE 1. If you don't have either or if it's INITIALLY DEFERRED then you'll face an INTEGRITY CONSTRAINT , because there will be a child record (in table 2). 这取决于表1上是否有ON DELETE CASCADEON DELETE SET NULL 。如果您既没有它又没有被INITIALLY DEFERRED那么您将面临INTEGRITY CONSTRAINT ,因为将有一个子记录(在表2中)。 You can read about it in How does cascade work in cases of delete/update for foreign key? 您可以在删除/更新外键的情况下如何级联工作中阅读有关它的内容

I believe your friend is right -- referenced tables are not automatically deleted just because you delete a table that has a foreign key. 我相信您的朋友是对的-引用的表不会仅因为您删除具有外键的表而被自动删除。 You can set up triggers that will do that, however. 但是,您可以设置触发器来执行此操作。

Foreign keys are mainly used to indicate relationships in a data model -- and they can also enforce data integrity between tables by adding extra stuff so that errors are thrown if data is entered without a corresponding key value existing in a reference table. 外键主要用于指示数据模型中的关系-外键还可以通过添加额外的内容来增强表之间的数据完整性,以便在没有引用表中存在对应键值的情况下输入数据时引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM