2011-04-27 69 views
0

我期待在RDBMS其中有幾個建議次會議,型號model,但一個將被選擇作爲接受或主之一。例如:如何嵌套集合與一個主要對象

create table Meeting (meetingId int); 
create table ProposedTime(meetingId int, dateAndTime datetime); 

但是,會有一個界面,用戶可以選擇其中一個建議時間,我需要保存該選擇。

我能想到的兩種選擇,各有缺點:

  1. 保持選擇提議在會議桌:

    create table Meeting(meetingId int, selectedProposalId int); 
    create table ProposedTime(proposalId int PK, meetingId int, dateAndTime datetime); 
    

    採用這種方法,它有可能是selectedProposalId是一個屬於不同會議的提案。

  2. Store上建議選擇一個標誌:

    create table Meeting(meetingId int); 
    create table ProposedTime(meetingId int, dateAndTime datetime, isSelected bool); 
    

    通過這種方法,它可能是兩個建議可以標記選擇。

我知道有「黑客」,以確保其完整性(2,在MS SQL你可以有一個過濾唯一索引,以確保只有一個被選中),但我寧願不承諾供應商特定的代碼。

我也沒事,只有在應用層執行的正確性,但仍有兩個選項打開。

你們有什麼建議?我也打開其他選項,如果任何人有任何想法;)

注意:我使用Rails 3,所以如果有一個首選的方式來處理這與ActiveRecord,我想聽到它。

回答

1

偉大的問題。我喜歡你正在評估潛在的不一致之處。在這種情況下,我會爭辯說第一個解決方案是正確的,只需稍作修改:ProposedTime的主鍵應該是一個包含meetingId的組合主鍵。

這有幾個原因:首先,一個proposedTime顯然不能存在沒有會議,更重要的是它不能沒有一個具體的會議存在。從本質上講,除了在會議的背景下,提議時間不能被定義,因此它的定義不應該讓它獨立。

其次,這種依賴性不能充分與meetingId表示爲強制屬性。例如,更新提議時間的meetingId字段是沒有意義的。 「讓我們上午9點到另一個會議!」。使會議主鍵的一部分顯式地阻止這種無意義的更新,因爲更新後的主鍵本質上是不同的。

最後,proposedTime具有邏輯不完整的關鍵事實是,你跑嘗試適當地使用它的時候到的第一件事。理想情況下,每個數據庫關係應該聲明一致。也就是說,如果你可以表達這種關係,「獅子有兩個父母」,一個父母應該不可能成爲一隻松鼠。顯然,性能和平臺限制意味着你不能總是達到這個目標,但是這種不一致可以被視爲一種「代碼味道」,這可能需要進一步調查。在你的情況下,修復看起來很小且性能高。

tl; dr:將meetingId添加到SuggestedTime的PK中,並使用您的第一個解決方案。

+0

我喜歡你的想法,但我在實踐中從未真正使用過複合主鍵。建議時間ID仍然是一個身份,因此在整個表中是唯一的?如果是這樣,複合主鍵看起來很奇怪。或者,應用程序圖層上是否生成了建議的時間標識,並且只在會議中唯一?如果是這樣,我很擔心安全地生成它們。或者有沒有辦法爲每個meetingId獨立播種一個標識列? – 2011-04-29 04:11:08

+0

考慮一個社交網站,用戶通過他們的電子郵件地址進行標識。你可以很容易地創建一個用戶表,如下所示: 'create table SocialUser(userId int PK,email varchar)' 顯然這會給你帶來問題,因爲同一封電子郵件可能會多次出現。然而你有一個獨特的主鍵!顯然,PK不足以真正識別記錄(聽起來很古怪)。正如我所看到的,您提出的TimeId的情況並沒有那麼不同。 proposedTimeId提供唯一性,但缺乏提供完整性所需的上下文。 – Darkmoth 2011-04-29 15:15:52

+0

我對我的評論中的可怕格式表示歉意......我仍在學習標記語法! – Darkmoth 2011-04-29 15:17:02