2010-11-08 33 views
0

我有以下表格:數據庫關係設計 - 在不同的表涉及兩個表兩次

Post 
Id int 

User 
Id int 

然後,我有表

Favorite 
PostId int 
UserId int 

和表

Vote 
PostId int 
UserId int 
IsUpVote bit 
IsDownVote bit 
LastActivity datetime2 

的問題是,如果我將Favorite和Vote合併到一張表中,那麼我會有類似

UserPost 
PostId int 
UserId int 
IsFavorited bit 
IsUpVoted bit 
IsDownVoted bit 
LastActivity datetime2 

IsDownVote不能夠再計算(因爲現在,我不能用「不存在:沒有投票;沒票了起來:否決」的格局了)和LastActivity只會反映最後一次投票已經改變(向上,向下,或刪除)所以我也許必須改變該字段的名稱或它的功能或。甚至兩者..

所以,問題是,基本上,如何錯是具有兩個與表A和B (Post,User)在這種情況下,它們由相同的主鍵(PostId,UserId)在這種情況下編入索引表,但其旨在用於不同用途?

回答

2

收藏夾和投票似乎是兩個不同的東西,所以恕我直言,你最好將它們作爲單獨的表格。正如你所提到的,如果你合併它們,你將失去功能,我看不到任何明確的好處合併它們,堅持你所擁有的除非你能提供一個真棒理由合併。

-1

雖然我不會說你應該做的桌子明智的,如果你使用int,而不是位和使用價值像0 1和-1做計算/比較,這樣你可以計算在相對所需的值簡單的方法。

說到關係數據庫,你應該總是瞄準3'rd範式關於你的表 - 嘗試尋找http://en.wikipedia.org/wiki/Database_normalization

乾杯!

+1

-1什麼是難點是使用位值做計算/比較(你可以做整數)?!?是否有一些原因,你喜歡用4個字節而不是1位存儲位值? – PerformanceDBA 2010-11-10 06:12:45

+0

他們在使用位值進行某些計算時遇到了麻煩,因此建議。我有我自己在我的日子實施了一個二進制編碼我的主要論文心電圖的標準,所以我沒有任何特別的問題。我的建議只是讓這個人跳過柵欄最低的地方,並解決他眼前的問題,同時要求他以第三方的正常形式閱讀,以使他的數據庫能夠進入正確的正常形式,有時候是最好的解決方案是一個快速解決方案,然後改進和重新考慮您的解決方案。 – 2010-11-10 19:34:55

+1

沒錯。然後,在完成所有這些後,更改數據庫和應用程序代碼。那將是一件可怕的勞動。首先要正確建模數據庫,並避免所有重新工作。 – PerformanceDBA 2010-11-25 02:14:13

1

沒有錯的。

我不是說DDL正確提供節目規範化的表,但他們是有點歸。當你已經確定了自己,兩個表有不同的用途,它們有不同的含義,所以在技術上(理論上,學術上,並在實踐中[代碼]),它們是正確的。

  • 「與同一父母」是不是一個標準(也有很多地方有相關的同父母很多表情況下,哪些是正確的)
  • 因此這樣的表將「具有相同的PK和FK「,所以這也不是一個標準。

只有擁有標準化的沒有真正的概念,並沒有負面表現的原因理念,將表明,「只是因爲他們有相同的父母(因此同一對鍵/索引)」,他們應該合併。

投票和收藏夾是兩個不同的事物,實體,採取的行動記錄。兩張表是正確的。

區別:IsDownVoted無法再比較的真正原因是它不適用於Favorite。你已經使用了一個指標(比特)來識別(儘管命名不正確);這實際上是一個空列的替代品。空值對性能沒有好處,並且您有指示器來識別數據的缺失並因此避免空值,這是一件好事,但這與單純地通過對它們進行規範化來打破規範化設計是分開的。

合併表將在所有訪問中執行較慢。當您從中選擇投票時,您必須排除收藏夾,反之亦然,但它將爲兩者執行I/O,因爲它們位於一起(PostId,UserId)。所以服務器永遠讀取兩倍的行數,使用兩倍的緩存;等等。然後,您將通過添加的「添加速度」(PostId,UserId,IsFavourited)的索引,使插入和刪除速度更慢(同時「加速」選擇)。網站被複合,保證;最好不要在第一時間搞混亂。

當數據庫增長時,您可以獨立地將列添加到投票和收藏夾中的任意一個,而不會影響另一個。在合併表中,它會引入複雜性。

您接受答案太快。