我正在为是否在我的SQL Server数据库上使用复合主键的哲学讨论而苦苦挣扎。我过去一直使用代理键,我正在挑战自己,离开我的舒适区去尝试一些不同的东西。我读了很多讨论,但还没有找到任何解决方案。当我不得不用复合PK更新记录时,我就遇到了困难。
例如,问题中的记录如下所示:
ContactID, RoleID, EffectiveDate, TerminationDT本例中的PK是(ContactID, RoleID, EffectiveDate)。TerminationDT可以为空。
如果在我的UI中,用户更改了RoleID,那么我需要更新记录。使用代理键,我可以执行Update Table Set RoleID = 1 WHERE surrogateID = Z。然而,使用复合键的方式,一旦复合键中的一个字段发生变化,我就无法引用旧记录来更新它,除非现在在UI中的某个地方维护对旧值的引用。
我没有在我的UI中绑定数据源。我打开一个连接,获取数据并将其存储在存储桶中,然后关闭连接。大家的意见是什么?谢谢。
发布于 2011-01-18 09:17:39
通过引用“旧记录”之类的概念,您所说的是关系具有独立于复合关键元素的语义含义。您需要一个键来引用旧记录,这一事实意味着复合键元素是不够的。当然,您仍然维护外键,但在我看来,您在这里需要一个主键,而且它不是通常意义上的代理键。
在我看来,使用代理键是没有负罪感的。
发布于 2011-01-18 09:23:20
您的思路是正确的,但是看看您的主键,我建议您查看一下normalization。我认为您应该尽量避免使用组合键,并尝试在每个表中使用一个主键,除非有必要。例如,您可以将RoleID设置为自己的表,其中包含角色描述以及定义角色的任何其他内容,并将其作为外键引用放在其他表中。
发布于 2011-01-18 10:45:21
首先是简单的部分:
看起来你的桌子是交叉引用的,不是吗?在这种情况下,我发现组合键工作得非常好,如果你的UI和其他库理解它们的话,这是一个很大的假设。现在很多UI都不支持,听起来你的也不支持。因此:
1)您使用组合键进行交叉引用是正确的,这是少数几个总是有意义的地方之一,但是:
2)你也可以在里面放一个代理键,如果这会让剩下的编码更容易的话,但是记住在这三列上添加一个唯一的约束。
更进一步,您可能需要一个检查约束来确保日期范围内没有重叠,因为数据库本身并不支持“范围主键”,这看起来就是您正在做的事情。
现在说到这里,让我进一步混淆一下。为什么要更新此行?正确的操作不是在原始联系人上设置终止日期,并强制创建一个新行来指示联系人的新角色吗?在这种情况下,您可能会保留组合并稍微修改一下UI,以允许/禁止某些操作。
https://stackoverflow.com/questions/4719595
复制相似问题