2011-05-02 41 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 。你不必擔心你的循環外鍵出錯。