2017-08-11 18 views
0

比方說,我有一個數據庫表叫products擁有的產品列表,與主鍵product_id是否可以將冗餘數據存儲在國外表的情況下記錄被刪除

然後我叫一個數據庫表purchase_order_products其中包含分配給採購訂單的產品列表,其中包含外鍵product_id

現在,如果我強制執行兩個表之間的參照完整性,它只需要一個採購訂單來引用一個產品,並且不可能從數據庫中刪除該特定產品(除非該產品也被刪除)。

看來我有幾個選擇:

1)實施參照完整性,不要讓產品永遠被刪除。

2)不強制執行參照完整性,如果有人查看產品不再存在的採購訂單,只需將產品名稱顯示爲「UNKNOWN」或「DELETED」。

3)最後一個選項是不僅將產品名稱存儲在products表中,還將其存儲在purchase_order_products表中並與外鍵一起存儲。顯然這是多餘的數據,但它可以讓產品從products表中刪除,同時仍允許用戶查看過去購買訂單中不存在的產品的名稱。

我對選項#3搖擺不定,但想知道什麼是「正確」的處理方式。

+0

刪除你是硬刪除還是軟刪除? –

+0

還有很多其他的選擇,甚至更多的組合。這使得你的問題「太廣泛」,直到你定義了需求。 –

回答

1

您可以強制執行參照完整性並使用ON DELETE SET NULL,然後在採購訂單的product_id爲空時顯示「UNKNOWN」或「DELETED」。因此,選項1和2不是相互排斥的。

選項3有效。擁有兩個product_name的副本並不是多餘的,如果它們使用的關係表達不同的謂詞。 Product <x>'s current name is <y>When purchase_order <z> was created, product <x>'s name was <y>不同。分別記錄當前和歷史價格是一種常見的技術,對於產品的名稱或任何其他屬性也可以做到這一點。

+0

謝謝,我同意爲歷史目的記錄價格和產品名稱。如果產品名稱由於某種原因將來會發生變化,那麼您可能*不希望這樣反映以前的訂單 – MrCarrot

1

沒有理由重複數據。一個簡單的解決方案是對產品實施軟刪除。最好的方法是將日期字段稱爲Deleted等適當的日期字段,並將其設置爲將來的日期,例如12/31/9999,用於當前產品。要刪除產品,只需將Deleted值設置爲刪除產品的日期。這樣,要列出當前可用的產品,請過濾掉以前產品Deleted

當顯示採購訂單時,請忽略Deleted值,以顯示所有產品,即使不再提供。或者,您可以通過某種指標顯示產品是否不再可用。

您可能還想創建一個忽略已刪除產品的視圖,因爲在創建新採購訂單時不適合顯示已刪除的產品。

您還想要在產品表上寫入刪除觸發器,以便將刪除過程轉換爲僅更改Deleted字段中的值。您還希望在API中具有一項功能,以允許某個產品在特定日期「被刪除」。也許該產品在一個月前被刪除,但數據庫未更新。或者該產品預計將在未來的日期被移除,因此請繼續並設置日期。當該日期到達時,產品將從當前產品視圖中消失。

+0

「編寫刪除觸發器[..]更改」Deleted「字段中的值 - I很好奇..這可能嗎? –

+0

是的,但我應該指定它必須是「而不是」觸發器。這意味着該表必須由一個視圖來支持,因爲只有視圖才能接受這些觸發器。 (除了SQL Server,就是這樣)。但是我通常會在大多數表格中使用至少一個視圖來提供應用程序和數據之間的抽象牆。 – TommCatt

相關問題