Sql 添加外键关系是否危险?

Sql 添加外键关系是否危险?,sql,database,Sql,Database,作为程序员,向对象添加引用是非常安全的,但添加外键关系(我认为)是非常危险的。通过添加FK关系,在实际删除行之前,必须更新从该外部表中删除行的所有查询,以正确删除绑定到该行的外键。如何搜索从此外部表中删除行的所有查询?这些查询可以隐藏在代码和存储过程中。这是维护噩梦的真实例子吗?这个问题有解决办法吗?你的说法根本不正确。建立外键关系时,可以将级联属性设置为cascade delete。一旦完成,当父记录被删除时,子记录将被删除,以确保没有孤立的记录。如果您使用正确的ORM解决方案,正确配置FK和

作为程序员,向对象添加引用是非常安全的,但添加外键关系(我认为)是非常危险的。通过添加FK关系,在实际删除行之前,必须更新从该外部表中删除行的所有查询,以正确删除绑定到该行的外键。如何搜索从此外部表中删除行的所有查询?这些查询可以隐藏在代码和存储过程中。这是维护噩梦的真实例子吗?这个问题有解决办法吗?

你的说法根本不正确。建立外键关系时,可以将级联属性设置为
cascade delete
。一旦完成,当父记录被删除时,子记录将被删除,以确保没有孤立的记录。

如果您使用正确的ORM解决方案,正确配置FK和PK,并启用级联删除,您应该不会有任何问题。

我不会这样说(以确认其他人提到的内容)-这通常由级联删除处理。如果你想这样做——或者通过仔细的程序来清理后面的东西

更大的系统是,您可以看到更多的“过程”,而较少的“自动化”(即级联删除)。对于较大的设置,DBA-s通常更喜欢在数据库维护阶段处理这些设置。通常情况下,不允许通过中间件应用程序代码删除记录,而只是将记录标记为“已删除”或“不活动”,并在以后根据组织中的数据库例程和程序进行处理(存档等)

除非你有一个非常大的代码库,否则这不是一个大问题。此外,通常,大多数Db代码都要经过一些DAL层,这些层很容易被遍历。或者,您也可以查询系统表中的所有关系和“依赖项”,许多例程都是为这样的代码维护而编写的(在“围栏”的两侧)。这并不是说这不是一个“问题”,只是和正常的数据库工作没什么不同——还有比这更糟糕的事情


这样,我就不会因为那件事而失眠了
。使用“过多”引用完整性约束(性能、维护)还存在其他问题,但这在DBA-s(以及一般的Db专业人员)中通常是一个非常有争议的问题,因此我将不深入讨论:)

从一开始就不应该设计没有外键的关系数据库。随着时间的推移,这是数据完整性差的保证

您可以像其他人建议的那样添加代码并使用级联删除,但这往往是错误的答案。有时您确实希望停止删除,因为您有子记录。例如,假设您有客户和订单。如果您删除了拥有订单的客户,那么您将丢失订单的财务记录,这将是一场灾难。相反,您可能希望应用程序得到一个错误,说明此客户存在订单。进一步的级联删除可能会突然让您删除数百万个子记录,从而在发生大型事务时锁定数据库。这是一种危险的做法,很少(如果有的话)在生产数据库中使用

添加FK(如果有关系,则需要),然后搜索从该表中删除的代码,并对其进行适当调整。考虑一下软删除不是更好的选择。这是您将记录标记为已删除或不活动的地方,因此它不再显示为数据输入选项,但您仍然可以看到现有记录。同样,您可能需要相当严格地调整数据库代码,以正确实现这一点。对于一个从一开始就设计糟糕的数据库,没有简单的修复方法

如果您认为您将有许多子记录并且确实想要删除它们,那么软删除也是一个不错的选择。这样,您可以标记记录,使其不再显示在应用程序中,并使用在非高峰时间运行的作业批量删除记录


如果您要添加一个新表并添加一个FK,处理起来肯定会更容易,因为您会在编写任何代码之前创建该表。

我知道,如果您尝试无序删除,SQL Server实际上会抛出一个错误(例如:在FK之前删除PK)但我不确定这是否适用于所有SQL。在RDBMS中强烈建议定义外键。当您要删除父表中的记录时,请清除子表中的相关记录,然后清除父表记录。您认为您所知道的关于外键的一切都是错误的。这个问题的答案很难填补你教育上的空白。你需要做更多的研究和阅读。当然层叠应该很少做,它也很危险。@HLGEM,我认为你的说法有点误导。有很多完全可以接受(并且安全)的实例,其中应该执行级联删除。例如,订单和订单详细信息记录。如果订单被删除(除非DBA认可孤立记录),则必须删除详细记录。当然,订单记录可能不应该首先被删除,但这是另一个问题。当然,子记录应该被删除,它们只是不应该在级联中自动删除,或者如果您有太多,您可以锁定服务器。我不知道有多少DBA会允许生产数据库使用级联删除。