为各种内容制作自己喜欢的系统

时间:2014-01-12 20:29:17

标签: asp.net sql-server database

我的数据库中有三种类型的内容。它们是歌曲,专辑和播放列表。专辑和播放列表只是歌曲的集合。我想让用户为他们每个人都喜欢。我用列做了表

LikeId UserId SongId PlaylistId AlbumId

用于存储喜欢的内容。例如,如果用户喜欢歌曲,我将歌曲的id放入SongId列,将用户的id放入UserId列。其他列将为null。它运作良好,但我不喜欢这个解决方案,因为它没有正常化。 所以我想问一下是否有更好的解决方案。

4 个答案:

答案 0 :(得分:0)

怎么样

LikeId  UserId LikeType TargetId

LikeType可以是“歌曲”,“播放列表”还是“专辑”?

答案 1 :(得分: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);

答案 2 :(得分:0)

作为惩罚的贪婪,我会使用三个表:UserLikesSongs,UserLikesPlaylists和UserLikesAlbums。每个包含一个UserId和对其他表之一的适当引用:歌曲,专辑或播放列表。

这还允许添加其他类型特定信息。也许专辑将来会支持最喜欢的曲目。

您始终可以使用UNION组合各种实体类型的数据。

答案 3 :(得分: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的结果。