2011-11-02 77 views
1

由於各種原因,我決定使用代理鍵(以種子身份的形式)。我的問題來自強制數據的唯一性。例如,以我創建數據庫的場景將所有書籍存儲在庫中。SQl設計問題。唯一索引/約束與代理鍵

isbn是分配給來自書籍出版世界某些魔術來源的所有書籍的唯一標識符。如果這本書是印刷的,那麼它有1個isbn,如果它是電子的,那麼它有另一個ISBN。

我們無法強制實施ISBN的唯一性,而無需將uniqueIndex覆蓋printedISBN和ElectronicISBN列。我的具體問題是,我們有這種類型的場景,我們需要強制實現數據的唯一性,但是我們使用的是代理主鍵,唯一的方法是強制實施數據唯一性,方法是在列上添加唯一索引喜歡執行。 這似乎與直覺相反,因爲如果我們在整個設計中遵循代理鍵方法,每個表都會有一個代理主鍵和一個唯一索引?這看起來很糟糕,我覺得我的設計技巧還不夠強大,找不到「正確的答案」。這些情況下的答案是什麼?

BookID INT IDENTITY (1,1) not null, 
Title varchar(25) not null, 
Author varchar(25) not null, 
PrintISBN char(13) not null, 
ElectronicISBN char(13) not null 
+1

一個可能的答案是,您將ISBN詳細信息標準化爲另一個表格,BookID,ISBN,ISBNType,OtherMeta字段 - 然後在ISBN上放置一個唯一約束。 – Andrew

+0

是有意義的。主鍵爲isbn有一列是isbn型,然後有typeID,ISBN型的另一個表。這可以讓我把任何類型的指導都放在那裏,只要我把它與以下類型聯繫起來,所以如果他們提出「isbnMark」版本,我可以很容易地適應它。 – gh9

回答

3

ISBN應歸一化到一個單獨的表。對於某本書,你可以處理多個ISBN,無論是精裝版還是軟性版,還是物理介質的盲文版,還是有聲讀物和電子書版本。我們甚至沒有考慮過這本書的翻譯版本是否會得到一個單獨的數字。

給定作者的書可以有多種方式發佈,我不認爲你應該限制ISBN的書籍可以有2 - 1印刷,1電子。

然後可以執行唯一性而沒有問題。

+0

偉大的評論和觀點。我正在解決一個更通用的問題,「你可以在具有代理鍵的表格中的第二列上強制執行唯一性」,並且你當然可以(並且你應該識別並選擇自然鍵),但是這個答案到達特定的核心OP的情況並導致思考更好的DB設計。 –

2

存在具有唯一索引和代理鍵是在同一個表中是唯一沒有問題。實際上,當使用代理鍵仍然聲明「自然鍵」索引並使它們唯一時(否則它僅僅是一個人工鍵,即它不是代理的任何東西)是一個要求。

我肯定會在ISBN上創建唯一索引來強制它們的唯一性,並讓查詢優化器知道列中的數據是唯一的。我們提交給查詢優化器的信息越多,執行結果計劃的效果就越好。

+0

不是這種方法藉助列上的額外索引借給大型數據庫文件嗎? – gh9

+0

你會用ISBN搜索嗎?如果是這樣,那並不是一個糟糕的指數。 13bytes x但是很多行。 –

+1

但是您的問題可能會出現在兩個ISBN中。當一本書沒有電子版本時,你會做什麼?你什麼時候只有電子版?一種解決方案可能是創建一個過濾的唯一索引,允許空值 - http://stackoverflow.com/questions/767657/how-do-i-create-unique-constraint-that-also-allows-nulls-in-sql-服務器 –

3

如果該書被打印出來,它有1個isbn,如果它是電子的,那麼它有另一個ISBN。

我懷疑這只是衆多分類中的一種,例如精裝,平裝,有聲讀物,Kindle,CD,下載。還要考慮多個出版商,語言,地區等。關於使用ISBN的好處之一是,您不必對此有任何疑問:您只需知道項目的ISBN編號,然後將其與另一項目的ISBN進行比較號碼來查明它們是否被認爲是相同的。

1

是的,每張桌子都應該有一個自然鍵(AKA「業務鍵」),不管它是否也有替代品。使用唯一性約束來強制執行密鑰。除了那些約束之外,正確使用索引是一個不同且基本上不相關的問題。

如果沒有業務需求分析,我認爲ISBN是否是您的表的正確業務關鍵是不可能的。完全可以說,應該有一些方法來識別您在業務領域內建模的實體。