2011-05-02 49 views
0

我简化了这一点,但我们有一个用户表和一个TestResult表,它们是由一个大型成熟的.net项目使用的大型现有sql2008数据库。用户被给予很多测试,并且这些被访问了很多,所以为了加快速度,用户表分别包含最后测试和正在进行的测试的CurrentTestResult和PendingTestResult。你也不能只看日期以找到当前的测试,因为有时测试可能会失效,与待处理相同。有关数据设计的问题,圆形外键

TestResult当然包含UserID的外键,User有2个指向TestResult的外键。这已经很长时间了,没有太多问题。偶尔,某种测试会被固定在用户身上,即使这不是他们的测试,很显然这不是完美的,我仍然需要追踪这个洞。

我们正在转向断开连接的模型,他们告诉我必须删除所有的圆形键。他们不想暂时丢弃和重新添加密钥,因为如果该过程失败,他们不知道该怎么做。不熟悉这个过程我不确定这是否合理,但是后来我找出修复引用的缺点后,这是个问题。

我可以看到这个问题的几种解决方案对我来说,所有这些都有其缺点。

A)其中最简单的就是丢弃2个外键。我对此没有太大的问题,因为FK限制只是图片的一半,除非它与正确的用户相关联,否则它仍然无效。为了保持密钥,我必须权衡风险与代码更改。

乙)我可以添加一个交叉引用表,以保持链接到当前和挂起。我认为这会给我基本上同样的保护,只有轻微的性能差异。我认为循环关键问题会消失,因为他们可以最后插入外部参照。我将有大量的代码更改。

C)我可以将2列添加到TestResults并标记当前和未决记录。现在的问题是我必须确保每个用户只设置一个标志,并且现在每次访问我的数据时都必须进行索引查找。所以我失去了保护,性能和我仍然有很多代码的变化。 D)???????????????????????????

我确定这是一个相当常见的模式,是否有“正确的”解决方案?

+0

有没有最好的解决方案,有没有更好的解决方案。 – dwidel 2011-05-02 16:05:12

回答

0

您的结构对我来说不是很清楚,但您可能可以隐藏可更新视图背后的部分或全部更改。

我有一种感觉选项B将是你最好的选择。你基本上在谈论这样的桌子,对吧? (空码)

create table xref (
    user_id integer not null references users (user_id), 
    current_test_result whatever not null references tests (test_id), 
    pending_test_result whatever references tests (test_id), 
    primary key (Hmmmmm) 
); 

待决测试结果是否必须为空?我想这并不重要 - 如果它必须是可空的,它在现有的表中必须已经可以为空。

+0

我实际上在考虑USERID,TestResultID,TestTypeID。至少我有另一种选择想想。我没有考虑可更新的观点。 – dwidel 2011-05-03 13:56:36

+0

可更新视图是SQL数据库如何实现逻辑数据独立性。他们构建起来有点痛苦,但他们真的很有用。 – 2011-05-03 15:21:21

0

您确定选项A实际上是一个性能问题吗?如果您的测试表中包含用户FK,然后是按时间顺序排列的某个索引 - 无论是IDENTITY列还是测试时间戳,那么当您从TEST表中选择TOP 2时,此索引将非常有用,其中user_id = X 。你不必担心你的循环外键出错。