【问题标题】:SQL Database layout/designSQL 数据库布局/设计
【发布时间】:2015-05-17 07:04:09
【问题描述】:

我正在创建一个由 SQLite 数据库支持的音乐播放器。有一个包含 id、标题、艺术家、专辑等的歌曲表。我目前正在尝试制作播放列表,我想知道我的设计是否有效。最初我想制作一个播放列表表,每个播放列表条目都有一个歌曲 ID 列表。然后我会在歌曲表中查询歌曲 ID 列表。类似于SELECT * FROM songs where id=this OR id=that OR id=.... 的东西。但是,我刚刚阅读了连接,所以现在我认为每个播放列表应该是它自己的表,播放列表表的条目只是歌曲表中的 id,我可以在歌曲 id 列上进行内部连接在特定的播放列表表和歌曲表之间。哪种方法会更有效?它们是等价的吗?

【问题讨论】:

    标签: sql database sqlite database-design


    【解决方案1】:

    当您发现自己正在考虑创建多个保存相似数据的相同表时,您可能应该退后一步,重新考虑您的设计,因为这与关系模型背后的理念背道而驰。存储“id 列表”的想法也是如此,我将其解释为某种数据数组,这也不适用于一个好的模型,因为一行(或元组)中的每个项目都应该只存储一个值。

    您的域的一种可能设计可能是这样的:

    Songs (SongID PK, SongAttributes (name, length etc) ...)
    Playlists (PlaylistID PK, PlaylistAttributes (like name, owner etc) ...)
    PlaylistSongs (PlaylistID FK, SongID FK)
    
    PK = Primary Key, FK = Foreign Key
    

    要为某个播放列表选择所有歌曲歌曲:

    select songs.name 
    from songs 
    join playlistsongs on songs.songid = playlistsongs.songid 
    join playlist on playlist.playlistid = playlistsongs.playlistid 
    where playlist.name = '???'
    

    至于您的问题:
    哪种方法更有效?它们是等价的吗?

    两者都不好,而且它们不相等。在第一个示例中,您可能会在检索和更新数据时遇到问题,而在另一个示例中,表的数量将与播放列表的数量成线性关系,并且您必须在运行时使用合适的表名注入每个查询 -时间 - 这真的是你不想要的。

    【讨论】:

    • 如何选择属于某个播放列表的所有歌曲?
    【解决方案2】:

    OR 语句很快就会变得低效,因此可以选择带有播放列表和播放列表 ID 的模型。

    示例: SONG ----> 带有 SONGID 列表的播放列表

    伪代码:

    CREATE TABLE SONG (
    song_id INT,
    name VARCHAR,
    other attributes);
    
    CREATE TABLE playlists (
    playlist_id INT,
    song_id INT REFERENCES FOREIGN KEY song(song_id),
    other playlist attributes);
    

    然后就可以加入列表了:

    SELECT a.*, b.*
    FROM playlists a 
    INNER JOIN song b ON a.song_id=b.song_id AND a.playlist_id=?;
    

    这将为您提供拥有 playlist_id X 的某个人的播放列表。

    【讨论】:

    • 我对 a.* 和 b.* 是什么感到困惑。您是指 SONG.* 和 playlists.* 吗?我假设这是特定表中的所有列?是什么意思?这是否意味着 a 现在是播放列表表?这种混淆的原因是什么?
    • a 和 b 是别名,因此我可以在执行连接、选择和 where 语句时输入更少的内容。在这种情况下,它声明: FROM playlists a 这也可以写成: FROM playlists AS a 所以在这种情况下,a 是播放列表的别名。您可以分配您想要的任何别名,并且在使用连接时经常需要它们,尤其是当您开始连接表时(在更复杂的数据模型或更复杂的查询中确实会发生这种情况)。
    猜你喜欢
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2015-10-13
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    相关资源
    最近更新 更多