简体   繁体   English

Firestore 子集合与数组

[英]Firestore subcollection vs array

First of, I know how Firestore works and have spent a lot of time, evaluating different approaches for a good structure.首先,我知道 Firestore 是如何工作的,并且花了很多时间来评估不同的方法以获得良好的结构。 Still I am considering following scenario:我仍然在考虑以下情况:

There is a database of known recipes.有一个已知食谱的数据库。 Users can add recipes, but they have to be confirmed to be real recipes and not just some variations.用户可以添加食谱,但必须确认它们是真实的食谱,而不仅仅是一些变体。 So every user can choose receipes from the user-generated list of recipes to state, that they know how to cook them (or add new ones).因此每个用户都可以从用户生成的食谱列表中选择收据来声明,他们知道如何烹饪它们(或添加新的)。

Now I want users to share their list of receipes with others, but this is where I am not sure how this can be best accomplished using Firestore.现在我希望用户与其他人分享他们的收据列表,但我不确定如何使用 Firestore 最好地完成这一点。 The trick is, that I want to show all the recipes at once, and don't want to paginate them.诀窍是,我想一次显示所有食谱,并且不想对它们进行分页。

I am currently evaluating two possibilities:我目前正在评估两种可能性:

Subcollections子集

Whenever a user shares his list, the user looking at said list will have to load the entire list of the recipes which can result in a high amount of document reads (I suppose realistically ~50, in very rare cases maybe 1000).每当用户共享他的列表时,查看所述列表的用户将不得不加载整个食谱列表,这可能导致大量文档读取(我想实际上是 ~50,在极少数情况下可能是 1000)。

Pros:优点:

  • More natural structure更自然的结构
  • Easier to maintain (eg deleting a recipe, checking if a specific one exists)更易于维护(例如删除配方,检查特定配方是否存在)
  • Easier to add fields (eg timeOfCreation, comment, personalRating, ...)更容易添加字段(例如 timeOfCreation、comment、personalRating 等)

Cons:缺点:

  • Can result in a high amount of reads on the long run从长远来看会导致大量读取

Arrays数组

I could save every known recipe (the id and an imageURL) inside the user's document (or as a single subdocument "KnownRecipes") within an array.我可以将每个已知的食谱(id 和 imageURL)保存在数组中的用户文档中(或作为单个子文档“KnownRecipes”)。 This array could be in form of这个数组可以是

recipesKnown: [{rid: 293ndwa, imageURL: image1.com, timeAdded: 8371201332}, 
               {rid: 9012831, imageURL: image1.com, timeAdded: 8371201871},
               {rid: jd812da, imageURL: image1.com, timeAdded: 8371201118},
               ...
              ]

Pros:优点:

  • I only need one document read whenever someone wants to see another user's list每当有人想查看另一个用户的列表时,我只需要阅读一个文档
  • Reading a user's list is probably faster读取用户列表可能更快

Cons:缺点:

  • It's hard to update a specific recipe (eg someone wants to change the imageURL: I need to change the list locally and send the entire document as an update to the server - since I cannot just change a single element in the array)很难更新特定的食谱(例如,有人想更改 imageURL:我需要在本地更改列表并将整个文档作为更新发送到服务器 - 因为我不能只更改数组中的单个元素)
  • When a user decides to have around 1000 recipes (this will maybe never happen, but it could), the 1MiB limit of the Firestore limit could be reached.当用户决定拥有大约 1000 个食谱时(这可能永远不会发生,但有可能),可能会达到 Firestore 限制的 1MiB 限制。 A possible workaround would be to create a seperate document and split those two arrays into these two documents.一种可能的解决方法是创建一个单独的文档并将这两个数组拆分为这两个文档。

For me, the idea with Subcollections seems to be the more "clean" solution to this problem, but maybe I am missing some arguments on why one of those solutions would be superior over the other.对我来说,子集合的想法似乎是解决这个问题的更“干净”的解决方案,但也许我遗漏了一些关于为什么其中一个解决方案优于另一个的论据。

My most common queries are as follows (ordered descending by importance):我最常见的查询如下(按重要性降序排列):

  • Which recipes can a user cook用户可以烹饪哪些食谱
  • Add a recipe a user can cook to the user's list将用户可以烹饪的食谱添加到用户列表
  • Who can cook a specific recipe (there is a Recipe -> Cooks subcollection)谁可以烹饪特定食谱(有食谱 -> 厨师子集合)
  • Update an existing recipe a user can cook更新用户可以烹饪的现有食谱

The answer to your question depends on the level of scalability you want to achieve.您的问题的答案取决于您想要达到的可伸缩性级别。

If by design the amount of sub-data you want to store is limited and very low, you should use arrays, since you reduce the number of document reads, which means lower costs.如果根据设计,您要存储的子数据量有限且非常少,您应该使用数组,因为您减少了文档读取次数,这意味着成本更低。

If your sub-data is supposed to increase "unlimitedly" over time, you should use sub-collections.如果你的子数据应该随着时间的推移“无限”增加,你应该使用子集合。

If you're building a database which is not supposed to scale in any direction (Proof of concept, very small business, etc.) just go with what you feel more comfortable with.如果您正在构建一个不应该在任何方向上扩展的数据库(概念验证、非常小的企业等),那就选择您觉得更舒服的方式。

I'm researching the same question...我正在研究同样的问题...

One of the questions is whether the data held in the document will be ever go pass 1MB that is the limit for a document.其中一个问题是文档中保存的数据是否会超过 1MB,这是文档的限制。 Researching a bit on how much it can be held in plain text in 1MB well it's a hell of a lot.研究一下它可以在 1MB 的纯文本中保存多少,这真是太麻烦了。 Still if it were to be incredible bigger it would crash in the end.尽管如此,如果它要大得令人难以置信,它最终还是会崩溃。 Thus if you think in a big-big way sub-collections.因此,如果您从大到大的方式考虑子集合。

If we had to use the Firebase element logic the answer would be sub-collections.如果我们必须使用 Firebase 元素逻辑,那么答案就是子集合。

Still I guess the major point is the data pulled.我仍然认为主要的一点是提取的数据。 If you call the user you will directly be pulling out that MB of data.如果您致电用户,您将直接提取该 MB 数据。 Instead with a sub-collection it won't load, even if you loaded it you can still lazy-load.相反,它不会加载子集合,即使您加载了它,您仍然可以延迟加载。

I guess for the kind of setup you are doing sub-collections.我猜你正在做子收藏的那种设置。

key is an additional collection 's con/pro key is an additional collection的 con/pro

key could help to avoid duplicates; key可以帮助避免重复; but this requires thinking of what is duplicate's definition (which might change);但这需要考虑什么是重复的定义(可能会改变);

array 's no-key behavior could be emulated via auto-id. array的无键行为可以通过自动识别来模拟。

ps @Thomas's list of pros/cons in the question has been quite helpful. ps @Thomas 在问题中列出的优点/缺点非常有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM