1

我創造我所創建以下數據庫模式的論壇頁面:問題在數據庫表中有關原子

Forum(questionId, postedByUserId, questionSubject, questionBody, TagIds); 

Tags(tagId, tagName); 

參賽作品中的主題將是這樣的:

(1, 1, 'sample subject', 'sample body', '1 4 2') ... 

而且樣本條目的標籤將是:

(1, 'C'), (2, 'C++'), (3, 'Java'), (4, 'Data Structure') ... 

現在的問題是,第一個正常形式說,所有的領域應該是原子,在這種情況下不滿足,但我認爲節省空間,就好像我正在創建一個新的表forum_tag(questionId, tagId);,那麼我認爲這會佔用更多的數據庫空間,但從概念上講是正確的。

所以我不知道該怎麼做,是否要做我現在正在做的事情,或者讓coloumns按照標準化原子化。

請說明哪個更好,爲什麼因爲有很多情況下,當我發現這樣的問題,但始終保持模糊不清,我該怎麼辦!

所以請幫助。

感謝提前:)

+1

正常化將幫助您維護數據庫。假設你必須刪除一個標籤。爲關係創建第三個表格將比查看TagIds字段並在那裏刪除它們更容易。我相信你可以考慮更多像這樣的例子。 – Averroes 2011-05-17 16:02:35

回答

1

空間在數據庫中便宜。檢索時間隨空間而變化,便宜得多。然而,檢索時間也可能受到鍵控訪問策略是否有效的影響,並且將由查詢優化器選擇。效果可能很戲劇性。

考慮以下對您提出的模式的檢索:找到其中一個相關標記爲「4」的所有論壇條目。對於大多數數據庫管理系統,這個查詢將需要通過整個論壇表的一個sequntial掃描。根據數據量,這可能是數百萬個磁盤I/O。

現在考慮結合表

ForumTags (ForumId, TagId) primary key (ForumId, TagId) 

而且,讓我們說,有除了對(ForumId,標籤識別)

自動索引上標籤識別的索引將導致指數同樣的查詢在其中一個索引中查找值「4」,並且需要少至十幾個磁盤I/O。

規範化的目標之一是對所有數據的鍵控訪問。第一種正常形式是依據這一目標。

我有過真實的生活情況,第一個正常形式或更好的模式可以與嵌入式列表模式進行比較。這些情況下的速度差異大約是50比1。

0

你應該讓代表論壇和標籤之間的關係的第三個表:

ForumTags(ftID,論壇,標籤)

這樣一來,你的數據庫是正確的規範化,因此向論壇添加和刪除標籤變得更加容易。不要擔心數據庫可能會帶來額外的空間,就像Walter Mitty所說的那樣:空間便宜,檢索要少得多。作爲一般規則:標準化總是一個好主意,除非另有明確證明

+0

但是這會在'forumtags'表中引起三個條目,但在之前的情況下這不會。即使我們可以得到更好的解決方案,它總是使用規範化的正確方法嗎? – codeomnitrix 2011-05-17 14:47:37

+0

@code:這是一個比通常在Stack上得到答案更哲學的問題。 Rik的答案會給你一個正確的規範化的模式,但是對於你的項目來說它是否是'正確的'更加鬆軟。沒有一種技術對所有情況都是完美的,你可能想質疑是否原子性是最重要的。在我看來,這種模式的原子性打破只會導致損壞或不好的論壇帖子,如果發生這種情況,這個帖子不難發現,並且遠離世界末日。 – tmesser 2011-05-17 14:53:24

+0

@YYY:這個評論讓我開始思考這個問題。因爲「沒有技術對所有情況都是完美的」。沒有任何概念性的方法可以在某些情況下做出更好的選擇。 – codeomnitrix 2011-05-17 15:26:55

1

我會去讓你的領域成爲原子。大多數時候,你有一個領域將價值觀念拼湊到一個領域,後來當你不得不不斷地將這些數據分開進行報告或分析時,最終會遇到麻煩。如果你想要做一些簡單的事情來獲得你的標籤數量呢?由於非原子數據,您甚至無法快速執行SELECT COUNT()。你也會遇到很大的問題,創建跨越參考論壇帖子與不同標籤的查詢。假設你想要查詢所有標有「編程」的論壇帖子?

將數據原子預先設置使其在您試圖查詢或分析數據時,可以更輕鬆地使用多個。這樣說,數據在進入你的數據庫之前就開始泛化,但你總是需要它的細節。嘗試將數據保存在離散塊中,以便更容易地瞭解具體情況。

+0

謝謝Pheedbaq :) – codeomnitrix 2011-05-18 05:44:08