Firebase有效地对nXn关系进行建模

时间:2019-11-12 12:05:17

标签: firebase google-cloud-firestore modeling

假设我有以下情况:

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

这是我想出的,为什么我不喜欢它们:

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
    })
})

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

1 个答案:

答案 0 :(得分: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获取事件文档。

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

  

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

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