2017-10-04 97 views
0

我正在定義一個表示由一個或多個零件項組成的頁面的實體。每個頁面必須至少定義一個部分。每個零件只屬於一個頁面。其中一個部分項目將成爲頁面上的「主」部分,其他所有部分將依靠主控部分。除此之外,主從部件的行爲相同。如何識別保持參照完整性的父記錄上的「首選」子女?

我正在看幾種不同的方式來表達這在SQL中。我可以想到幾個選項,每個選項都有優點和缺點。我確信沒有人「正確的答案」,但我正在尋找哪些方法隱藏了複雜性的反饋意見,這些複雜性將在以後引發我的興趣。約束和CASCADE觸發器是可取的,這樣其他方可以在需要時安全地修改表,但是我想避免需要複雜邏輯的設計。

在配置時,用戶需要選擇主控的能力,而不允許將0或多個部件標記爲主控。在運行時,每個部分都需要確定它是否是主設備,或者需要依靠主設備獲取信息。

我的目標平臺是Microsoft SQL Server 2008或更高版本。下面的示例使用int鍵只是因爲它適用於較小的示例 - 在實現時我傾向於使用GUID鍵。

選擇1 - 上主部標誌

create table [Page] (
    PageKey int identity primary key, 
    PageName varchar(30) not NULL 
) 
go 
create table [Part] (
    PartKey int identity primary key, 
    PartName varchar(30) not NULL, 
    PageKey int not null, 
    constraint fkPage foreign key (PageKey) references [Page](PageKey), 
    IsMasterPart bit not NULL default 0 
) 

優點:簡單的數據來理解;在我正在增強的基礎應用程序中使用類似的方法;零件記錄知道它是主機而不查找頁面記錄上的數據。 缺點:強制只有一個主控會要求觸發器拒絕違反規則的更新或應用層代碼,或兩者兼而有之。

選擇2 - 頁面上外鍵

create table [Page] (
    PageKey int identity primary key, 
    PageName varchar(30) not NULL, 
    MasterPartKey int not NULL 
) 
go 
create table [Part] (
    PartKey int identity primary key, 
    PartName varchar(30) not NULL, 
    PageKey int not null, 
    constraint fkPage foreign key (PageKey) references [Page](PageKey), 
    IsMasterPart bit not NULL default 0 
) 
go 
alter table [Page] 
    add constraint fkMasterPart 
    foreign key (MasterPartKey) references [Part](PartKey) 

優點:DRI防止刪除主部件;只能有一個主人部分;不能有一個頁面沒有主部分 缺點:潛在的雞和蛋的問題與分配PK/FK值

  • 什麼是模式(或者是有一個),用於插入家長和第一個強制性的孩子一個操作?
  • 刪除最後一個孩子和父母的模式(或者是否存在)是什麼模式,當其他部分存在時仍然會阻止刪除Page和主體部分?

我懷疑我錯過了一個或兩個必要的細節以給出一個很好的答案。請問,我會更新。

+0

它是這樣的評論,讓我分心,然後再回到問題的核心>「我會在執行時傾向於使用GUID鍵」。現在我想拋開你的問題並談論這個評論。爲什麼你會用整套的GUID? [不斷增加的集羣密鑰 - 集羣索引辯論.........。重要! - 金伯利特里普](http://www.sqlskills.com/blogs/kimberly/ever-increasing-clustering-key-the-clustered-index-debate-again/) – SqlZim

+0

我想我用那個評論淹沒了水。這並沒有真正的相關性,但是在我向前邁進之前,我一定會閱讀你的鏈接。謝謝! – Bruce

+0

我閱讀了您的文章,並欣賞關於頁面拆分的評論(真的,因爲我也是)。在我的情況下,最大的表格將只包含數百行,如果我樂觀的話可能會包含數千行。將鍵值分配給另一個數據庫(維護交叉引用)的密鑰值比擁有統一增加的密鑰更重要。設置數據,而不是交易數據。不過,謝謝你的回擊。這就是我來這裏的原因。 – Bruce

回答

0

我將與選項1一起使用。您對選項1的缺點不正確:可以使用調用UDF的CHECK CONSTRAINT強制執行「唯一且唯一的一個主」規則。這就是我會用的。

+0

如果他們想讓不同的部分成爲主人呢?有沒有一個很好的方式來執行這個原子?也許在新的部件上設置標誌將清除它在舊的主控制器上,或者我應該寫一個更新...設置IsMasterPart =(1 - IsMasterPart)PartKey in(@old,@new)? – Bruce

+0

它可以通過一個精心構造的更新來自動完成(我認爲):SET SETMasterPart = CASE when somecondtion THEN 1 ELSE 0 END ...' –