我来自 SQL 背景,所以我在设计 NoSQL firebase 架构时遇到了问题。我习惯于使用“WHERE”子句查询任何内容,而在 firebase 中这样做似乎更困难(尽管性能很容易弥补它!)。
我正在为歌曲存储“轨道”对象。这些对象具有键/值对,例如艺术家名称、曲目标题、流派、评级、创建日期等,如下所示:
tracks
|_____-JPl1zwOzjqoM8xDTFll
|____ artist: "Bob"
|____ title: "so long"
|____ genre: "pop"
|____ rating: 52
|____ created: 1403129692781
|
|_____ -JPv7KnVi8ASQJjRDpvh
|____ artist: "Mary"
|____ title: "im alright now"
|____ genre: "rock"
|____ rating: 70
|____ created: 1403129692787
我网站上的默认行为是列出所有这些曲目,最新添加的曲目出现在列表顶部。我可以将我的 $priority 设置为要创建,然后将其变为负数(已创建 * -1)以实现我相信的这种效果。
但在未来,我希望能够通过其他方式过滤/查询列表,例如:
检索具有摇滚、流行或嘻哈流派的所有曲目。
检索评分为 80 或更高且在过去 7 天内添加的所有曲目。
如何在firebase中实现这一点?我的理解是,实际上只有两种方式来订购数据:
通过“ID”值,它具有“firebaseURL.firebaseio.com/tracks/id”的物理位置,在我的情况下,当我添加轨道时,它会自动为我选择。这没关系(我认为),因为我有用于列出详细信息的各个跟踪页面的页面,并且我网站上的 URL 类似于“www.mysite.com/tracks/-JPl1zwOzjqoM8xDTFll”。
通过使用 $priority,在我的例子中,我使用了“created”值,以便按正确的日期顺序排列我的列表。
鉴于我设置的方式(如果有更好的方法,请告诉我),有没有一种方法可以轻松查询特定类型或特定评级?
我读了博客“非规范化你的数据是正常的”(https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html),我想我明白了。根据 Anant 的描述,实现我想要的一种方法可能是在 firebase 中为一个流派创建一个新对象并列出那里的所有曲目,如下所示:
tracks
|______ All
|_____ -JPlB34tJfAJT0rFT0qI
|_____ -JPlB32222222222T0qI
|_____ -JPlB34wefwefFT0qI
|______ Rock
|_____ -JPlB32222222222T0qI
|_____ -JPlB34tJfAJT0rFT0qI
|______ Pop
|_____ -JPlB34wefwefFT0qI
博客中的前提是硬盘空间很便宜,但用户的时间却不是。因此,存在重复数据是可以的,因为它允许更快的读取。
这是有道理的,我不介意这种方法。但这只有在用户只想从一种流派中选择所有曲目时才有效。如果他们想从摇滚和流行音乐中获取所有曲目怎么办?每次有人提交任一类型的歌曲时,我是否必须存储另一个名为 Rock&Pop 的对象并在其中存储一首曲目?
genre
|_______pop-rock
|_________ -JPlB34tJfAJT0rFT0qI (a rock song)
|_________ -JPlB34wefwefFT0qI (a pop song)
|_________ -JPlB32222222222T0qI (a rock song)
此外,存储整个轨道对象或仅使用 trackid 的引用是否更有意义?例如,在 /genre/pop 下:
Should I store just the reference?
genre
|______ pop
|______ -JPlB34wefwefFT0qI
Or, Should I store the entire track?
genre
|______ pop
|______ -JPlB34wefwefFT0qI
|___ artist: "bob"
|___ title: "hello"
|___ genre: pop
|___ etc..
两种方法之间有性能差异吗?我在想也许后者会更快,因为我不需要查询每个单独的曲目以获取其他详细信息,但我只是想确定一下。
我已经多次重做我的 firebase 架构。我做了一些改进,但是随着我的应用程序变得越来越大,更改它变得更加昂贵并且消耗更多时间。如果我能在花大量时间重做其余代码以再次匹配之前最后一次解决这些问题,那就太好了。
感谢您对此的任何帮助,非常感谢。如果您需要更多信息,请告诉我。