Database-Design

數據庫設計 - 具有共享標記的不同對象

  • March 5, 2013

我的背景更多是網路程式而不是數據庫管理,所以如果我在這裡使用了錯誤的術語,請糾正我。我試圖找出為我將要編碼的應用程序設計數據庫的最佳方法。

情況:我在一個表中有報告,在另一個表中有建議。每個報告可以有許多建議。我還有一個單獨的關鍵字表(用於實現標記)。但是,我只想將一組關鍵字應用於報告和建議,以便搜尋關鍵字可以為您提供報告和建議作為結果。

這是我開始的結構:

Reports
----------
ReportID
ReportName


Recommendations
----------
RecommendationID
RecommendationName
ReportID (foreign key)


Keywords
----------
KeywordID
KeywordName


ObjectKeywords
----------
KeywordID (foreign key)
ReportID (foreign key)
RecommendationID (foreign key)

本能地,我覺得這不是最優的,我應該讓我的可標記對象繼承自一個共同的父對象,並標記該註釋父對象,這將給出以下結構:

BaseObjects
----------
ObjectID (primary key)
ObjectType


Reports
----------
ObjectID_Report (foreign key)
ReportName


Recommendations
----------
ObjectID_Recommendation (foreign key)
RecommendationName
ObjectID_Report (foreign key)


Keywords
----------
KeywordID (primary key)
KeywordName


ObjectKeywords
----------
ObjectID (foreign key)
KeywordID (foreign key)

我應該採用第二種結構嗎?我在這裡遺漏了任何重要的問題嗎?另外,如果我選擇第二個,我應該使用什麼作為非通用名稱來替換“對象”?

更新:

我正在為這個項目使用 SQL Server。這是一個內部應用程序,有少量非並髮使用者,所以我預計不會有高負載。在使用方面,關鍵字可能會被謹慎使用。這幾乎只是為了統計報告的目的。從這個意義上說,無論我採用什麼解決方案,都可能只會影響任何需要維護該系統的開發人員……但我認為只要有可能就實施良好的實踐是很好的。感謝所有的洞察力!

您的第一個範例的問題是三連結表。這是否需要報告或建議中的一個外鍵始終為 NULL,以便關鍵字僅以一種或另一種方式連結?

在您的第二個範例中,從基表連接到派生表現在可能需要使用類型選擇器或 LEFT JOIN,具體取決於您的操作方式。

鑑於此,為什麼不直接明確並消除所有 NULL 和 LEFT JOIN?

Reports
----------
ReportID
ReportName


Recommendations
----------
RecommendationID
RecommendationName
ReportID (foreign key)


Keywords
----------
KeywordID
KeywordName


ReportKeywords
----------
KeywordID (foreign key)
ReportID (foreign key)

RecommendationKeywords
----------
KeywordID (foreign key)
RecommendationID (foreign key)

在這種情況下,當您添加需要標記的其他內容時,您只需添加實體表和連結表。

然後您的搜尋結果看起來像這樣(如果您想要一個結果列表,請參閱仍然進行類型選擇並將它們轉換為對象結果級別的泛型):

SELECT CAST('REPORT' AS VARCHAR(15)) AS ResultType
   ,Reports.ReportID AS ObjectID
   ,Reports.ReportName AS ObjectName
FROM Keywords
INNER JOIN ReportKeywords
   ON ReportKeywords.KeywordID = Keywords.KeywordID
INNER JOIN Reports
   ON Reports.ReportID = ReportKeywords.ReportID
WHERE Keywords.KeywordName LIKE '%' + @SearchCriteria + '%'
UNION ALL
SELECT 'RECOMMENDATION' AS ResultType
   ,Recommendations.RecommendationID AS ObjectID
   ,Recommendations.RecommendationName AS ObjectName
FROM Keywords
INNER JOIN RecommendationKeywords
   ON RecommendationKeywords.KeywordID = Keywords.KeywordID
INNER JOIN Recommendations
   ON Recommendations.RecommendationID = RecommendationKeywords.ReportID
WHERE Keywords.KeywordName LIKE '%' + @SearchCriteria + '%'

無論如何,在某個地方都會進行類型選擇和某種分支。

如果您在選項 1 中查看如何執行此操作,它是相似的,但使用 CASE 語句或 LEFT JOIN 和 COALESCE。當您使用更多連結的東西擴展選項 2 時,您必須繼續添加更多的 LEFT JOIN,其中通常找不到東西(連結的對像只能有一個有效的派生表)。

我認為您的選項 2 沒有任何根本性的錯誤,您實際上可以使用視圖使其看起來像這個提案。

在您的選項 1 中,我很難理解您為什麼選擇三聯表。

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