考慮這個數據庫有4個表(星號主鍵):添加唯一約束的關係,2度遠
Products(*ProductId*, SkuText, ...)
ProductRevisions(ProductId, *RevisionId*, ...)
Orders(*OrderId*, ...)
OrderItems(*OrderId*, *ProductRevisionId*, Quantity, ...)
的想法是,一個產品SKU可以有多個版本(例如2016年的版本的產品與2015版相比)。業務規則是這樣的,即Product
的Order
只能有一個單獨的ProductRevision
,例如,訂單不能請求同一產品的2014和2016版本,他們只能擁有2014年版或 2016版。
按說這不會是一個問題:OrderItems
表將有一個ProductId
柱,用UNIQUE
約束上OrderId
和ProductId
。但是,由於OrderItems
的引用ProductRevisionId
(所以參考ProductId
是間接的),這是一個簡單的UNIQUE
約束失敗和架構將接受以下數據,即使它是爲每業務規則無效:
Products
ProductId, SkuText
1, 'Kingston USB Stick'
ProductRevisions
ProductId, RevisionId, ...
1, 1, '2014 model'
1, 2, '2016 model'
Orders
OrderId
1
OrderItems
OrderId, ProductRevisionId, Quantity
1, 1, 100
1, 2, 50 -- Invalid data! Two revisions of the same Product should not be in the same order.
我需要的是這樣的:
ALTER TABLE OrderItems
ADD CONSTRAINT UNIQUE (OrderId, SELECT ProductId FROM ProductRevisions WHERE RevisionId = OrderItems.ProductRevisionId)
我不想通過增加一個明確的ProductId
列進行非規範化我OrderItems
表,因爲這增加了潛在的故障點,如果給定的父/子關係ProductId
和ProductRevisionId
被改變,那麼數據變得無效。
我有什麼選擇?
」這種方法的缺點是產品只能出現在每個訂單中只有一行。「 - 這不是一個缺點,這正是我所追求的:) – Dai