Database-Design

內容相同的關係表,自定義解決方案

  • May 26, 2016

因此,假設我正在建構一個可以為FOO添加評論的應用程序。通常我會有這樣的事情:

foo和表foo_comments,其中foo_comments包含idfoo_id和其他列。

現在這是我在我的應用程序中使用評論的唯一方式。我確實從某人那裡得到了一條說明,如果他們將來會更新應用程序並且他們也想為BAR添加評論,我應該從現在開始添加一些自定義的東西,即使我現在不需要它。所以我被建議添加這樣的東西

一個表註釋(用於一般用途),它將包含一個類型列(其中類型可以是一個 int 表示所指表的表:foo、bar 或其他東西)和一個type_id列,它將包含來自的行的 id主表。

所以這是一個好習慣嗎?我應該建構這樣的東西,只是因為將來可以更改應用程序嗎?或者我只是將它與foo_comments表一起保存,然後如果應用程序將為BAR表添加評論,我也會創建一個bar_comments表。

我會把它們分開。儘管細節有所不同,但您的情況很像One True Lookup Table反模式。通過組合,您將遇到定義外鍵(指向哪個父級?)等問題。索引策略本質上是將組合表拆分為其組成部分。等等…

合併的理由是 Foo 和 Bar 是一些更抽象實體類型的子類型,並且所有註釋都可以掛起這個超類型。

你有很多因素需要權衡,但這是我要開始的地方:

  1. FOO 評論和 BAR 評論的列會完全一樣嗎?
  2. 您是否需要對 foo 和 bar 上的所有評論進行分組,同等對待(例如,您是否需要數據庫查詢來按日期/時間對 foo 和 bar 評論進行排序/過濾/計數)?
  3. BAR 需要評論的可能性有多大,以及 BAR 之外的其他“模型”(我將開始使用 MVC 術語“模型”來表示 FOO/BAR/ETC)需要評論的可能性有多大,以及有多少模型可能需要評論嗎?

您提到的兩種主要方法是:創建帶有“類型”欄位的評論表,或根據需要為每種評論類型使用單獨的表。

所以,從問題 #1 開始:

如果評論表可能需要不同的欄位,那麼根據應用程序的要求和軟體,您可能會在嘗試在 foo 和 bar 之間“共享”相同的評論表時遇到問題。在這種情況下,您最好將它們分開。使用統一表,您可以隨時為 FOO 評論未使用的 BAR 評論添加欄位,但如果評論表不能相同,則可能會導致應用程序開發中的額外麻煩。

如果表相同,我會考慮#2:

如果您需要能夠在同一數據庫查詢中對 foo 和 bar 評論進行分組/排序(如果您需要將它們分組在一起或計為完全相同的事物的不同類型),那麼您可能需要建構一個統一的評論表. 我將在最後討論我對此的建議。

如果我可以假設永遠不需要將評論作為一個實體進行查詢(或者這不太可能,或者如果他們這樣做,我可以通過分別查詢每個表並使用程式碼對結果進行排序來做到這一點),這將使我更傾向於走向不同的桌子。

當使用單獨的(但相同的)表時,可以使用幾乎相同的程式碼建構用於獲取它們的數據庫查詢。通過使用繼承、模型關係或共享行為/輔助類(許多軟體框架共有的概念),您可以創建一個類來在每個單獨的表上執行相同的數據庫查詢,只需交換數據庫表名父類的每個實例或子類都配置為使用。表名可以是程式碼中模型的變數/屬性。通過這種方式,您無需編寫或維護完全獨立的程式碼即可獲得單獨表的好處。

最後,我總是會考慮#3。我可能需要將評論擴展到 BAR 以及其他模型的可能性越大,我就越有可能使用統一表,因為它不需要我創建越來越多相同的表,這維護起來可能很乏味(將一列添加到 12 個不同的評論表比添加一個列要多)。

現在 -

如果由於您的任何要求,您要使用完全統一的表格:

在您的統一評論表中,添加您的comment_type_id列。如果可能的話,我會強烈考慮為該列創建一個索引,以便更快地過濾和排序。您可以按照您的建議將其設為整數。

在您的應用程序中,您現在可以將任何模型與評論表中它自己的特定行相關聯,只需為其分配一個comment_type_id.

comment_type_id然後應該在查詢中使用模型以僅匹配comment_type_id列中具有相同值的註釋,而不是將查詢定向到完全不同的表。comment_type_id每個可以有相關評論的模型,因為 FOO/BAR/ETC在插入和查詢同一個評論表時都會有不同的使用,並且您可以在它們之間共享“評論”模型的程式碼。同時,如果要抓取所有類型的所有評論,只需要查詢一張表即可。

添加其他評論類型可以通過將 comment_type_id 屬性添加到任何需要它自己的評論的模型來管理,然後確保模型共享/繼承相同的程式碼來管理其相關評論。

我可能會建議創建一個表格來管理評論類型。像這樣的表對於記賬很有用,可以用來從程式碼中查找註釋類型名稱,但完全是可選的。

一個comment_types表可能只是id(自動增量)和name(作為標籤)列。首先,你會有類似的東西:

id | name 1 | foo 2 | bar

統一表中的危險可能在於將評論連結回 FOO 或 BAR。程式碼必須檢查comment_type_id註釋列,然後查詢相應的 FOO/BAR/ETC 模型表以獲取數據。這當然是可行的,並且框架具有處理關係的方法,但在軟體方面需要更多的工作和設置。

引用自:https://dba.stackexchange.com/questions/138534