【问题标题】:Make own like system for various content为各种内容制作自己的系统
【发布时间】:2014-01-31 12:40:15
【问题描述】:

我的数据库中有三种类型的内容。它们是歌曲、专辑和播放列表。专辑和播放列表只是歌曲的集合。我想让用户为他们每个人点赞。我用列制作了表格

LikeId UserId SongId PlaylistId AlbumId

用于存储喜欢。例如,如果用户喜欢歌曲,我将歌曲的 id 放入 SongId 列,将用户 id 放入 UserId 列。其他列将为空。它工作得很好,但我不喜欢这个解决方案,因为它没有标准化。 所以我想问一下是否有更好的解决方案。

【问题讨论】:

    标签: asp.net sql-server database


    【解决方案1】:

    您应该只创建 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 的结果。

    【讨论】:

      【解决方案2】:

      怎么样

      LikeId  UserId LikeType TargetId
      

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

      【讨论】:

      • 感谢您的回答。它比我的解决方案更有趣且更紧凑。如果我找不到更好的,也许我会使用它。但我会寻找更规范的解决方案。
      • 此解决方案允许您添加新的类似类型(例如“艺术家”),而无需进一步更改数据库。 LikeType 的查找表将完成设计。
      【解决方案3】:

      您的解决方案很好。它有一个很好的功能,您可以设置与其他表的显式外键关系。此外,您可以通过添加检查约束来验证是否设置了其中一个值:

      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);
      

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2010-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-19
          • 1970-01-01
          • 2020-04-30
          相关资源
          最近更新 更多