2009-03-04 50 views
0

比方說你有以下實體在數據庫:你如何構建你打算重用的實體?

Image http://lh6.ggpht.com/_UpGtM3B8h1U/Sa7SqfWmgDI/AAAAAAAAAHE/epqtm7EnoFg/test.gif

你希望能夠把註釋添加到所有三個其他實體表(用戶,客戶和項目)。你會如何設置?

  1. 將tableName和FKId添加到Note表中?
  2. 每個相關注組創建一個單獨的表(即,ClientNote,UserNote)
  3. 每個外鍵(用戶ID,客戶端Id等)

創建注意一個單獨的字段我似乎是在選項2和3之間來回切換,儘管如果有一個優雅的實現,我會達到1。選項2很有吸引力,因爲沒有空值。選項3很有吸引力,因爲一張紙條感覺就像一張紙條,不管它與什麼相關聯。

有什麼想法?

+0

圖像似乎已丟失。 – webclimber 2009-03-04 19:27:40

回答

1

我通常會使用選項2.我不強調數據庫中表的數量。

最大的問題是,這些筆記是作爲一個單獨的項目處理嗎?例如,你是否會說:「向我展示所有筆記,無論是爲客戶還是用戶還是項目。」我想不出任何有用的情況。您通常會說「給我看這個客戶的筆記」或「給我看這個項目的筆記」。

由於它們在邏輯上不是一個項目,所以我建議不要試圖將它們塑造成一個物品。

0

我通常看到的處理方式是在選項1中。最重要的是,這對於人類來說是一個相當簡單的方法,可以看到發生了什麼。正如你所說,缺點是SQL變得不那麼優雅。

雖然這只是有點。實際上,即使它可能感覺有點笨重,結果查詢清晰可讀。你只需要在你添加新表的地方添加sql到新代碼中。

當您直接操作筆記時,您只需處理一個表格。

+0

嗯.... 1實際上是我最不喜歡的方法,因爲使用數據庫工具很難保持參照完整性。 – anopres 2009-03-04 19:45:13

+0

數據庫工具只能帶你到目前爲止。如果你想在數據庫中使用它,你可能不得不忍受觸發器或其他供應商特定的方法(Postgres規則是我的最愛)。 – SingleNegationElimination 2009-03-05 00:12:42

0

還有第四個方法(我建議):添加一個唯一的ID注意事項表,字段noteId給用戶,客戶和項目

+0

我希望能夠爲每個實體添加多個筆記。我應該把它寫在原來的問題上。 – anopres 2009-03-04 19:39:21

0

什麼做可能取決於票據是否田野上你實體之間的需求是相同的。如果它們是相同的,那麼我可能會有一個Notes表(如果需要更改所有的註釋,例如,在一個步驟中添加修訂日期字段)與Notetype(用戶,客戶端,項目),noteID和來自相應表格的id以及所有你需要的筆記相關字段。這最大的問題是FK關係將不得不通過觸發器而不是FK進行管理。你不想放入一個無效的userid,但是由於整個列不包含userids,所以你不能只設置一個FK關係。另一方面,如果稍後添加另一個實體,則可以在不影響表結構的情況下(儘管您仍然需要修改觸發器),這是在不同字段中使用ID的問題。這也意味着你將無法使用級聯更新或刪除,這會使刪除記錄(或更改自然鍵(顫抖))變得更加困難。

如果您對筆記的哪些字段的需求在實體之間不同,我會爲每個實體創建單獨的Notes表。

如果您打算在所有啓用項之間的每個查詢中擊中Notes表,那麼您可能需要爲每個實體分開表以減少鎖定和阻塞問題。然而,注意事項可能不需要經常出現,所以它可能不會太糟糕。

0

選項3.擁有一個身份作爲主鍵,並且具有共享Note表的任何表的外鍵列。我以這種方式處理電子郵件,電話,地址等。

我知道的唯一缺點是如果你有10個錶鏈接到注 - 你會有10個外鍵列。

我有選擇1的問題是,它感覺就像你正在創建一個人爲的外鍵(使用TableName/Pkid,實際上不是用戶/項目主鍵的一部分,這只是Pkid)。這可能只是我個人的偏見,我從來沒有覺得這是很好的設計,但我不能完全說出原因。

0

我認爲,在這種情況下,您應該明確避免解決方案1。
您鬆動了完整引用,在沒有動態SQL的情況下查詢數據庫變得不可能,並且總是需要2次查詢才能選擇一些筆記!
你不應該在這種簡單的情況下使用這種方式。

正如我所看到的,我使用選項4(在項目,客戶端和用戶上添加字段note_id)。如果你需要多行註釋,這不是問題。你只需添加一個額外的表(讓我們說note_set),使其成爲n-1關係。

客戶端(CLIENT_ID,note_set_id) 用戶(USER_ID,note_set_id) 項目(PROJECT_ID,note_set_id)

note_set(note_set_id) 說明(note_id,note_set_id,標題,正文)

的主要問題這個解決方案,是給出了一個筆記,你不能找到最初的「實體」沒有在三個表上創建一個聯盟。這對我來說似乎並不是一個大問題,但如果是這樣,那就選擇3吧。

最後,選項2也不錯,但它不是我所謂的「重用」。

請原諒我的英語。