创建外键的危险。 nHibernate和SQL Server

时间:2011-11-21 15:14:25

标签: c# sql-server nhibernate

我继承了一个旧的破旧数据库,并希望在现有的关系列中加入大量的外键,这样我就可以使用像nHibernate这样的关系。

我对键的领域缺乏经验,虽然我觉得我理解它们是如何工作的,但我有一部分是害怕的,或者以某种方式破坏了数据库。

例如,我发现" cascade on delete"的概念。我不认为数据库上目前有任何外键,所以我猜这不会影响我......但我怎么检查才能确定?

我需要注意哪些其他风险?

在某种程度上,我喜欢在没有外键的情况下使用nHibernate,但从我所看到的情况来看,这是不可能的?

3 个答案:

答案 0 :(得分:4)

NHibernate不需要在要使用的数据库上存在外键,但我仍然建议尽可能添加外键,因为外键是 好东西 他们确保您的数据库的参照完整性是应有的。

例如,如果我的数据库中有一个User和一个Comment表,我要删除碰巧发表两条评论的用户1,没有外键我现在有两个没有所有者的评论!我们显然不希望这种情况发生。

这是外键的来源,通过声明UserComment表中的外键,我们的数据库服务器将确保我们无法删除用户,除非它没有注释与他或她相关(再也没有)。

将外键引入数据库是一件好事。它将公开现有的无效数据。它将保留现有的有效数据,有效。您可能必须对已经失控的表执行一些数据操作(即创建“未知用户”或类似的东西并更新所有不存在的键以指向它,这是在检查之后需要做出的决定数据的含义)。

如果现有应用程序崩溃,它甚至可能会导致一些问题,例如它不会删除它应该执行的所有数据(例如不删除我示例中的所有注释)。但从长远来看,这是一件好事,因为它暴露出事情出错的地方并且允许你修复它们而不会使数据和数据库在此期间陷入更糟糕的状态。

NHibernate cascades与外键分开,并且是NHibernate允许您在删除父项时确保删除所有子对象的方式。例如,这允许您确保对数据模型所做的任何更改都不会违反您的外键关系(这会导致数据库异常并且不会应用任何更改)。我个人更喜欢自己照顾这个,但是由你决定是否以及如何使用它们。

答案 1 :(得分:4)

将外键放在没有它们设计的数据库上的最大问题(这表明原始数据库设计者不称职,因此还有许多其他问题需要修复),是否接近于您有100%的可能存在没有父密钥的孤立数据。您需要弄清楚如何处理这些数据。其中一些可以被抛弃,因为它不再以任何方式使用,只是浪费空间。但是,如果它与订单或任何财务相关,则需要保留数据,在这种情况下,您可能需要定义可以将记录与之关联的“未知”父记录。首先查找并修复所有错误数据,然后添加外键。

谨慎使用级联更新和级联删除,因为如果需要更改大量记录,它们可以锁定数据库。另外,在许多情况下,如果存在现有记录,则希望删除失败。例如,您不希望通过财务记录级联删除。如果删除用户会删除过去的订单,这是一件非常糟糕的事情!如果您不使用级联,则可能会遇到错误代码,当密钥到位后您无法再删除或更改记录时,数据会变得很糟糕。因此,在准备好密钥后,请彻底测试所有删除和更新功能。

答案 2 :(得分:0)

外键在规范化数据库中形式化关系。您正在讨论的外键约束会执行诸如阻止创建重复键或删除定义仍在使用或引用的实体的字段之类的操作。这称为“参照完整性。

我建议使用某种建模工具来绘制所谓的ERM或实体关系模型图。这将帮助您概述数据的存储方式以及更改的用途。

完成此操作后,您应该考虑数据是否处于合理(例如第二或第三范式)标准化程度。特别注意具有主键的每个实体,并且数据完全描述密钥。您还应该尝试删除冗余并将非原子字段拆分为新表。 “每个非关键属性必须提供关于密钥,整个密钥的事实,除了密钥之外什么都没有,所以帮助你Codd。”如果您发现数据未标准化,那么在适当的情况下修复任何严重的结构问题和/或重构将是一个好时机。

此时,添加外键和约束将推车放在马前。在尝试保护数据之前,请确保数据完整性。你需要先做一些准备工作,然后约束会让你不那么破旧的新改造的数据库保持最佳状态。约束将确保没有人决定对将数据变成混乱的规则进行例外处理。花点时间让数据更好地组织起来,并在之后锁上门。