firebase - Firestore 子集合与数组
问题描述
首先,我知道 Firestore 是如何工作的,并且花了很多时间评估不同的方法以获得良好的结构。我仍在考虑以下情况:
有一个已知食谱的数据库。用户可以添加菜谱,但必须确认它们是真实的菜谱,而不仅仅是一些变体。因此,每个用户都可以从用户生成的食谱列表中选择收据来说明他们知道如何烹饪(或添加新的)。
现在我希望用户与其他人分享他们的收据列表,但我不确定如何使用 Firestore 最好地完成这一点。诀窍是,我想一次显示所有食谱,并且不想对它们进行分页。
我目前正在评估两种可能性:
子集合
每当用户分享他的列表时,查看该列表的用户将不得不加载整个食谱列表,这可能会导致大量文档读取(我想实际上约为 50,在极少数情况下可能为 1000)。
优点:
- 更自然的结构
- 更容易维护(例如删除一个配方,检查一个特定的是否存在)
- 更容易添加字段(例如 timeOfCreation、comment、personalRating...)
缺点:
- 从长远来看,可能会导致大量读取
数组
我可以将每个已知的食谱(id 和 imageURL)保存在数组中的用户文档中(或作为单个子文档“KnownRecipes”)。这个数组可以是
recipesKnown: [{rid: 293ndwa, imageURL: image1.com, timeAdded: 8371201332},
{rid: 9012831, imageURL: image1.com, timeAdded: 8371201871},
{rid: jd812da, imageURL: image1.com, timeAdded: 8371201118},
...
]
优点:
- 每当有人想查看另一个用户的列表时,我只需要阅读一个文档
- 读取用户列表可能更快
缺点:
- 很难更新特定的配方(例如,有人想要更改 imageURL:我需要在本地更改列表并将整个文档作为更新发送到服务器 - 因为我不能只更改数组中的单个元素)
- 当用户决定拥有大约 1000 个食谱时(这可能永远不会发生,但它可以),可能会达到 Firestore 限制的 1MiB 限制。一种可能的解决方法是创建一个单独的文档并将这两个数组拆分为这两个文档。
对我来说,子集合的想法似乎是解决这个问题的更“干净”的解决方案,但也许我错过了一些关于为什么其中一个解决方案优于另一个的论点。
我最常见的查询如下(按重要性降序排列):
- 用户可以烹饪哪些食谱
- 将用户可以烹饪的食谱添加到用户列表中
- 谁可以烹饪特定的食谱(有一个 Recipe -> Cooks 子集合)
- 更新用户可以烹饪的现有食谱
解决方案
您的问题的答案取决于您想要实现的可扩展性级别。
如果根据设计,您要存储的子数据量有限且非常低,则应使用数组,因为您减少了文档读取次数,这意味着成本更低。
如果您的子数据应该随着时间的推移“无限”增加,您应该使用子集合。
如果您正在构建一个不应该向任何方向扩展的数据库(概念证明、非常小型的企业等),请选择您觉得更舒服的数据库。
推荐阅读
- command - 如何在 git 中提交特定的更改
- python - 解析格式为 20120101 1:00 的数据
- angular - 在主题订阅方法中调用时,Angular 5 ng-bootstrap 模态未正确显示
- matlab - 如何在 MATLAB 中合并两个函数?
- c++ - Qt5,在行中设置文字大小编辑
- docker - Docksal:如何启用 HTTPS / SSL?
- ruby-on-rails - 结合两个 each_with_object 迭代器
- sql-server - SQL Server:CASE 中的“=”语法错误
- java - Java Regex:如果缺少,请在字符串的开头和结尾添加引号
- r - 将文件导出到 R 中的相对路径