【问题标题】:Firebase efficiently model nXn relationshipFirebase 有效地建模 nXn 关系
【发布时间】:2019-11-12 22:52:03
【问题描述】:

假设我有以下场景:

我有多个活动,多个用户可以参加。此外,用户可以参加多个活动。在保持数据一致性的同时存储所需信息的最佳方式是什么?

以下是我的想法以及我不喜欢它们的原因:

collection "events" -> event document -> subcollection "users" -> user document 问题: 每个用户都存在于每个事件上,从而导致每个用户的多个文档。我不能只更新用户信息,因为我需要写入每个相关的事件文档并获取相关的用户文档。 如果试图尽可能减少读/写,那真是一场灾难 例如:

this.afs.collection('events').get().then(res => {
    res.forEach(document => {
        document.ref.collection('users', ref => ref.where('name', '==', 'Will Smith')).get()
        //Change name accordingly
    })
})

collection "users" -> user document -> subcollection "events" -> event document 问题: 每个事件都存在于每个用户上,从而导致每个事件的多个文档。 (与第一种情况相同的问题,只是相反)

collection "users" and collection "events" 每个都有用户和事件作为从属于他们的文档。 有一个数组attending_events,其中包含相关的事件ID。 问题: 排序事物的一种 SQL 方式。需要使用forEach() 函数通过单独的查询获取每个文档。 例如

this.afs.collection('events').doc(eventId).get().then(res => {
    res.users.forEach(elem => {
        this.afs.collection('users').doc(elem.name).get()
        //Change name accordingly
    })
})

我缺少什么,是否有更好的方法来建模所需的架构?

【问题讨论】:

  • 请编辑您的问题并添加您打算执行的查询。
  • 请查看更新后的问题。
  • 所以你想获取一个用户正在参与的所有事件以及来自特定事件的所有用户,对吗?
  • 不,我希望能够更改用户信息或事件信息,而无需获取数百个文档。

标签: firebase google-cloud-firestore modeling


【解决方案1】:

当使用collection "events" -> event document -> subcollection "users" -> user document

这并不像你想象的那么糟糕。这种做法称为非规范化,是 Firebase 的常见做法。如果您是 NoSQL 数据库的新手,我建议您观看此视频,Denormalization is normal with the Firebase Database 以获得更好的理解。它适用于 Firebase 实时数据库,但同样的规则适用于 Cloud Firestore。

我希望能够更改用户信息或事件信息,而无需获取数百个文档。

如果您认为用户详细信息会经常更改,那么您应该考虑在每个user 对象下存储一个array 的事件ID 并且使用子集合。同样,您还应该在每个event 对象下添加一个array 的UID。您的新架构应如下所示:

Firestore-root
   |
   --- users (collection)
   |    |
   |    --- uid (document)
   |         |
   |         --- events: ["evenIdOne", "evenIdTwo", "evenIdThere"]
   |         |
   |         --- //Other user properties
   |
   --- events (collection)
        |
        --- eventId (document)
             |
             --- users: ["uidOne", "euidTwo", "uidThere"]
             |
             --- //Other event properties

由于您只持有引用,因此当用户名发生更改时,无需在events 子集合中存在的所有用户对象中更新它。但请记住,在这种方法中,例如,要获取用户分开的所有事件,您应该创建两个查询,一个从用户文档中获取事件 ID,第二个是根据这些事件 ID 获取事件文档。

基本上这是在使用非规范化和将数据存储在数组中之间的权衡。

在保持数据一致性的同时存储所需信息的最佳方式是什么?

通常,我们会根据要执行的查询来创建数据库模式。有关更多信息,我还建议从以下帖子中查看我的答案:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 2011-11-08
    • 2016-12-25
    • 2017-11-06
    • 2017-12-21
    • 2015-03-10
    • 2023-03-26
    相关资源
    最近更新 更多