【问题标题】:Modeling a three-way many-to-many relation in Firebase在 Firebase 中建模三向多对多关系
【发布时间】:2017-11-06 10:30:50
【问题描述】:

我目前正在开发一款用于体育统计的应用,并且正在研究 Firebase 是否/如何处理我需要的数据和关系。

因为 Firebase 似乎不支持 WHERE a = x AND b = y 的等效项,所以我不确定哪种方法适合我的用例。

我的系统中有以下实体:

  • 国家 - 世界上的一个国家。
  • 运动 - 一项运动。
  • 地区 - 一个国家的地区。对于每项运动,国家/地区的区域划分方式都不同。

将出现一个页面,您可以在其中选择国家和运动,并显示地区列表。

对于乡村和体育来说,这似乎很容易:

{
    "countries": {
        "-Kl9JB-XRzZyz_GkRiW8": {
            "name": "The Netherlands"
        }
    },
    "sports": {
        "-Kl9JB-XRzZyz_GkA83b": {
            "name": "football"
        }
    }
}

但是区域呢?由于一个地区与一个国家和一项运动相关联,这样的事情似乎是合乎逻辑的:

{
    "regions": {
        "-Kl9JB-XRzZyz_GkRiWa": {
            "name": "West",
            "country_key": "-Kl9JB-XRzZyz_GkRiW8",
            "sport_key": "-Kl9JB-XRzZyz_GkA83b"
        }
    }
}

但是,这会导致问题,因为据我所知,我无法查询db.ref().child('regions'),然后按country_key = asport_key = b 服务器端过滤。我可以获取一个国家/地区的所有地区,并按体育客户端过滤(反之亦然),但这不是一个非常优雅(或可扩展)的解决方案。

我想了几个解决方案:

  • 为每个地区添加一个复合国家/运动键,例如"country_key:sport_key": "-Kl9JB-XRzZyz_GkRiW8:-Kl9JB-XRzZyz_GkA83b"
  • 添加一个新实体sports_countries,并让每个区域指向其中一个实体。

当然,这只是我整个模型的一部分。完整的模型有更多的关系,例如地区有比赛,国家有俱乐部,俱乐部有球队,球队在比赛,球员在球队等等。

您将如何在 Firebase 中解决此问题?或者,也看看数据模型的其余部分,你会告诉我我应该坚持使用关系数据库而不是 Firebase?

【问题讨论】:

    标签: firebase firebase-realtime-database many-to-many nosql


    【解决方案1】:

    对于三向关系,您可以组合 country_keysports_key(不建议超过 2 个)。

    {
        "regions": {
            "-Kl9JB-XRzZyz_GkRiWa": {
                "name": "West",
                "combined_key": "-Kl9JB-XRzZyz_GkRiW8-Kl9JB-XRzZyz_GkA83b"
            }
        }
    }
    

    然后一起查询:

    ...ref("regions").orderBy("combined_key").equalTo(country_key + sports_key)
    

    同样,如果您尝试按超过 2 个字段进行过滤,则不建议这样做,但适用于 2 个字段。

    这个question 有更多见解。

    【讨论】:

    • 为什么说这种方法不建议使用两个以上的键?我不是说你错了,但我很好奇你的推理。
    • 因为某些区域可以用不太具体的查询来查询。这不会很好地工作。就像区域 1 通过过滤器 1 一样,所以得到它。但是没有通过过滤器 1 2 和 3 所以不要,没有办法辨别。
    • 如果您的过滤器是强制性的,并且每个区域只能出现一次,那么该方法将起作用。
    • 好的。所以它特定于这个用例(我承认没有完全阅读)?这是一个很好的理由! :-) 感谢您的澄清。
    • 我现在正在使用这个解决方案,到目前为止它工作正常。一个小的区别是我在两个键之间使用了:,因此如果需要,我可以在之后轻松拆分组合键。不知道这是否真的有用!
    猜你喜欢
    • 2014-05-26
    • 2015-08-19
    • 2013-05-27
    • 2018-03-28
    • 1970-01-01
    • 2017-01-02
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多