2014-01-12 25 views
0

我的數據庫中有三種類型的內容。他們是歌曲,專輯和播放列表。專輯和播放列表只是歌曲的集合。我想讓用戶對他們每個人都喜歡。我製作了列表爲各種內容製作自己喜歡的系統

LikeId UserId SongId PlaylistId AlbumId 

用於存儲喜歡。例如,如果用戶喜歡歌曲,我會將歌曲ID放入SongId列和用戶ID到UserId列中。其他列將爲空。它運行良好,但我不喜歡這個解決方案,因爲它沒有正常化。 所以我想問問是否有更好的解決方案。

回答

0

您應該創建3個表格 - 一個用於與播放列表,歌曲和相冊配對的用戶。他們會是這個樣子:

CREATE TABLE PlaylistLikes 
(
    UserID INT NOT NULL, 
    PlaylistID INT NOT NULL, 
    PRIMARY KEY (UserID, PlaylistID), 
    FOREIGN KEY (UserID) REFERENCES Users (UserID), 
    FOREIGN KEY (PlaylistID) REFERENCES Playlists (PlaylistID) 
); 
CREATE TABLE SongLikes 
(
    UserID INT NOT NULL, 
    SongID INT NOT NULL, 
    PRIMARY KEY (UserID, SongID), 
    FOREIGN KEY (UserID) REFERENCES Users (UserID), 
    FOREIGN KEY (SongID) REFERENCES Songs (SongID) 
); 
CREATE TABLE AlbumLikes 
(
    UserID INT NOT NULL, 
    AlbumID INT NOT NULL, 
    PRIMARY KEY (UserID, AlbumID), 
    FOREIGN KEY (UserID) REFERENCES Users (UserID), 
    FOREIGN KEY (AlbumID) REFERENCES Albums (AlbumID) 
); 

這裏,在主鍵有兩列,除非你想,要成爲可阻止用戶喜歡的歌曲/播放列表/專輯不止一次( - 然後將其刪除或可能會在「喜歡的人數」列中跟蹤)。

你應該避免把所有3種不同類型的喜歡放在同一個表中 - 不同的表應該用來表示不同的東西。你想避免「一個真正的查詢表」 - 這裏有一個答案,詳細說明爲什麼:OTLT

如果你想要查詢所有3個表,你可以創建一個視圖,這是3個表之間的一個UNION結果。

0

如何

LikeId UserId LikeType TargetId 

哪裏LikeType可以是 「歌」, 「播放列表」 或 「專輯」?

+0

謝謝你的回答。它比我的解決方案更有趣,更緊湊。也許我會用它,如果我找不到更好的。但是我會搜索更多標準化的解決方案。 – romandemidov

+0

該解決方案將允許您添加新的相似類型(例如「藝術家」),而無需進一步更改數據庫。 LikeType的查找表將完成設計。 – FJT

0

您的解決方案很好。它具有很好的功能,可以爲其他表設置顯式外鍵關係。此外,你可以驗證準確的值之一是通過添加一個檢查約束設置:

check ((case when SongId is null then 0 else 1 end) + 
     (case when AlbumId is null then 0 else 1 end) + 
     (case when PlayListId is null then 0 else 1 end) 
    ) = 1 

沒有發生存儲所有三個NULL值,開銷。這對於三個值來說相當小。

您甚至可以添加一個計算列來獲取其值存儲:

WhichId = (case when SongId is not null then 'Song' 
       when AlbumId is not null then 'Album' 
       when PlayListId is not null then 'PlayList 
      end); 
0

至於懲罰饞嘴,我會用三個表:UserLikesSongs,UserLikesPlaylists和UserLikesAlbums。每個包含UserId和對其他表格之一的適當引用:歌曲,專輯或播放列表。

這也允許添加其他類型特定的信息。也許相冊將支持未來最喜歡的曲目。

您可以隨時使用UNION合併來自各種實體類型的數據。