Firebase有效地对nXn关系进行建模 [英] Firebase efficiently model nXn relationship

查看:100
本文介绍了Firebase有效地对nXn关系进行建模的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下情况:

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

I have multiple events, that multiple users can attend. Also, users can attend multiple events. What's the best way of storing the required information with maintaining data consistency?

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

Here's what I came up with and why I don't really fancy them:

collection "events" -> event document -> subcollection "users" -> user document 问题: 每个用户都存在于每个事件中,从而导致每个用户有多个文档.我不能只更新用户信息,因为我需要写到每个相关的事件文档并获取相关的用户文档. 如果尝试使读写次数最少,那真是一场灾难 例如:

collection "events" -> event document -> subcollection "users" -> user document Problem: Each user exists on each event, resulting in multiple documents of each user. I can't just update user information as I would need to write to every relevant event document and fetch the relevant user documents. Really a disaster if trying to make the least reads/writes possible E.g.:

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" -> user document -> subcollection "events" -> event document Problem: Each event exists on each user, resulting in multiple documents of each event. (Same problem as in the first scenario, just the other way around)

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

collection "users" and collection "events" with each having users and events as documents subordinate to them. There's an array attending_events which has the relevant event id's in it. Problem: Kind of the SQL way of sorting things. There's the need of getting each document with a seperate query using a forEach() function. E.g.

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

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

What am I missing, is there better approaches to model the desired architecture?

推荐答案

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

这并不像您想的那样糟糕.这种做法称为非规范化,是涉及Firebase的一种常见做法.如果您不熟悉NoSQL数据库,建议您观看以下视频,对于Firebase数据库,正常化是正常的以便更好地理解.它适用于Firebase实时数据库,但对于Cloud Firestore,适用相同的规则.

It's not so bad as you might think. This practice is called denormalization and is a common practice when it comes to Firebase. If you are new to NoSQL databases, I recommend you see this video, Denormalization is normal with the Firebase Database for a better understanding. It is for Firebase realtime database but the same rules apply in the case of Cloud Firestore.

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

I want to be able to change user information or event information without the need of fetching hundreds of documents.

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

If you think that user details will be changed very often, then you should consider storing under each user object an array of event IDs and not use a subcollection. In the same way, you should also add under each event object an array of UIDs. Your new schema should look like this:

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获取事件文档.

Since you are holding only references, when the name of a user is changed, there is no need to update it in all user objects that exist in events subcollection. But remember that in this approach, to get for example all events a user is apart off, you should create two queries, one to get the event IDs from user document and second to get event documents based on those event IDs.

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

Basically it's a trade-off between using denormalization and storing data in arrays.

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

What's the best way of storing the required information with maintaining data consistency?

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

Usually, we create the database schema according to the queries we intend to perform. For more infos, I also recommend to see my answer from the following post:

这篇关于Firebase有效地对nXn关系进行建模的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆