这是我的第一个使用NoSQL数据库的项目,我想知道如何以最有效的方式构建数据。
我正在制作一项小型服务,存储广播电台播放的所有歌曲。用户可以“喜欢”这些歌曲。所以,基本上我有以下数据:
Song: Id, Artist, Title
Play: SongId, Time (when was the song played)
Like: SongId, UserName, Time (when did the user click the like button)
我需要对该数据运行各种查询。例如:最后X首歌曲播放+喜欢计数,最近X天播放的歌曲,喜欢特定歌曲等等。
首先,我考虑将所有内容存储在具有嵌套播放和类似信息的单个文档中。但这使得一些查询变得非常复杂,并且需要我在客户端进行排序等操作,但我希望保持从数据库传输的数据量很小。
我还在考虑在内存中缓存一些最常用的查询。在做这样的事情时是否有任何一般性建议?
答案 0 :(得分:1)
由于歌曲的数量,播放次数,用户数量都会很大,因此使用嵌入式文档不会起作用,所以你不得不回到更多的关系模型和每个都有一个集合。
我要反规范化的是将歌曲信息放入Play文档和Like文档中,这样您就可以为任何用户呈现播放列表和喜欢,而无需对歌曲集合进行任何“连接”。
歌曲:Id,艺术家,标题
播放:SongId,Time(播放歌曲的时间),艺术家,标题
喜欢:SongId,UserName,Time(用户点击“赞”按钮的时间),艺术家,标题,UserId
答案 1 :(得分:1)
如果使用嵌套结构查询变得困难,您可以选择以下几个选项:
为歌曲创作单独的文档与播放vs喜欢。当然,这些文件可以互相参考。
保持嵌套,但也让客户端插入创建反向关系的其他存根文档。也就是说,对数据进行非规范化。在像Mongo这样的分布式数据存储中,对数据进行非规范化比在关系数据库世界中更容易接受。
使用mapreduce查询来聚合所需的数据。随着数据的增长,这可能会变得昂贵,因此您可能会更好地使用另一个文档数据存储库,如CouchDB,它可以在新数据进入时连续运行您的映射器。(我不知道Mongo是否具有此功能或不)。
(请不要为此向我投票)使用SQL数据库。您的数据相当正常,因为歌曲,播放等的特征不会因记录而异。因此,在这里使用关系数据库可以提供您所追求的查询灵活性,而不会牺牲数据灵活性(因为您并不真正需要它)。 RDBMS不会横向扩展,但这是一个性能问题,一旦你成功就可以解决这个问题。
这就是我看到它的方式 - 祝你好运!