2017-04-23 64 views
2

我在將RSS源中的數據標準化爲數據庫時遇到了問題。組織和規範化RSS源類別數據

每個帖子將有idcategories

我遇到的問題是categories是一個沒有預先定義大小的列表。通過1NF我應該拆分列表起來,使得每列只有原子數據:

+----+----------+ 
| id | name | 
+----+----------+ 
| 1 | flying | 
| 2 | swimming | 
| 3 | throwing | 
| 4 | sleeping | 
| 5 | etc  | 
+----+----------+ 

然而,博客文章可以有多個類別標籤。這意味着posts表可以有一個標記類別的id列表。

或者,categories表可以有兩個ID:

+----+--------+----------+ 
| id | postId | name | 
+----+--------+----------+ 
| 1 |  1 | flying | 
| 2 |  1 | swimming | 
| 3 |  1 | throwing | 
| 4 |  2 | flying | 
| 5 |  2 | swimming | 
| 6 |  2 | etc  | 
+----+--------+----------+ 

postsid將引用postId柱。但是,有重複的數據,這是不好的。

最後,我曾想過的另一種方法是把所有的類別在一個表:

+----+--------+----------+----------+----------+-----+ 
| id | flying | swimming | throwing | sleeping | etc | 
+----+--------+----------+----------+----------+-----+ 
| 1 |  1 |  1 |  1 |  1 | 1 | 
| 2 |  0 |  1 |  0 |  0 | 0 | 
| 3 |  1 |  1 |  0 |  0 | 1 | 
| 4 |  0 |  0 |  1 |  1 | 1 | 
+----+--------+----------+----------+----------+-----+ 

1代表中國出席並0代表中國缺席,在postsid引用id。這種方法不會有任何重複的數據。但是,可以隨意創建博客類別,這使得維護這樣的表格變得很困難,因爲每次有新類別時我都需要更新它。

如何將我的數據庫放入3NF,消除重複同時保持可維護性?

+0

你沒有清楚地解釋你的表格。此外,你是不是指「替代類別表」postId引用帖子表ID,反之亦然;並且最後一個表id引用Posts表id,而不是反之呢? (也許行中的行與Post中的行是1:1)(「References」意思是「只能有值出現在」中)。請:1.給每個表一個唯一的名字。 2.給一個帖子表格的例子。 3.在正確的方向使用「參考」。 4.根據我的回答,對於每個表格*給出謂詞(按列參數化的句子模板),根據其中的行將其變爲真語句。 – philipxy

回答

0

TL; DR「重複的數據」是一個bugbear。瞭解設計和規範化。從關於任意情況的明確直截了當的相關陳述的行/表開始。到目前爲止,所有你需要的是:

-- [id] identifies a post with ... 
Post(id, ...) 
-- post [id] is tagged [name] 
Post_Category(id, name) 

有重複的數據,這是不好的

正是你怎麼看「重複數據」是什麼?爲什麼你認爲這是「不好」?

關於將相同的值作爲行的列或行的一部分值的多次出現,沒有任何內在的壞處。重要的是表格中的行是否以某種方式說明情況的重疊。

標準化通過對其進行迴歸的投影來替換表格。這意味着,它取代的表,它的行人士說,表,其行說:「一些東西」和「其他的東西」分開(即有謂語)「一些東西東西」有關列的值。把「AND」放在這樣的行/表中並不總是壞的。當只有一個AND時,規範化表示恰好在沒有共享列集總是在兩個表中的任何一箇中保存唯一值集時分解爲特定的一對錶。

把所有的類別在一個表

雖然沒有任何關於這樣會導致正常化分解它的設計,你最後一個表是一個「壞」的設計。 (有時這種重複相似列的設計被認爲違反了「1NF」或「規範化」的概念,但這是一種誤解)。例如,它的行說:「(post [id]被標記爲'飛行'和[飛行] = 1 OR post [id]沒有被標記爲'flying'並且[flying] = 0)AND(post [id]被標記爲'swimming'並且[swimming] = 1或post [id]沒有被標記爲'游泳'並且[游泳] = 0)AND ...「的時候,我們可以將一個表Post_Category的行標記爲」post [id]被標記爲[name]「。例如,我們不能編寫詢問所有類別的詢問,而不明確提及所有類別。例如,如果我們添加一個新的類別,那麼我們必須在表格中添加一個新的列,然後如果我們希望我們的過去的查詢重新指定所有類別,那麼他們就必須添加新的列,以指代所有類別。

PS目前還不清楚你爲什麼引入ID。有我們這樣做的原因,但你應該這樣做的一個原因。 (規範化不會引入ID。)例如,如果帖子不能被我們想要記錄的其他信息唯一標識,則引入帖子ID。

+0

你能否在第二部分中重新解釋你的答案並解釋你的例子?我應該怎麼做? –

+0

查看我編輯的帖子。我的謂詞中存在一些錯誤,但我只是將這個(無關緊要的)部分刪掉了。 – philipxy