數據庫設計 - 具有共享標記的不同對象
我的背景更多是網路程式而不是數據庫管理,所以如果我在這裡使用了錯誤的術語,請糾正我。我試圖找出為我將要編碼的應用程序設計數據庫的最佳方法。
情況:我在一個表中有報告,在另一個表中有建議。每個報告可以有許多建議。我還有一個單獨的關鍵字表(用於實現標記)。但是,我只想將一組關鍵字應用於報告和建議,以便搜尋關鍵字可以為您提供報告和建議作為結果。
這是我開始的結構:
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 中,我很難理解您為什麼選擇三聯表。