在 Firebase 中构建关系

Posted

技术标签:

【中文标题】在 Firebase 中构建关系【英文标题】:Structuring Relationships in Firebase 【发布时间】:2015-03-10 09:55:36 【问题描述】:

我的 Firebase 中有两个项目:providersservices,我正在尝试找出使用 Firebase 推荐的扁平化架构方法构建和建立关系的最佳方法。

我的数据如下所示:


  "services" : 
    "hip_replacement" : 
      "title" : "Hip Replacement"
    
  ,

  "providers" : 
    "the_blue_hospital" : 
      "title" : "The Blue Hospital"
    
  

我想将这两个项目链接在一起,这样如果您要访问 Hip Replacement 页面,Blue Hospital 会显示在其下方,如果您要访问 The Blue Hospital 页面,Hip Replacement 会显示在该页面下方.本质上是一种双向关系。

构造这样的东西的最佳方法是什么?我的思路是这样的:


  "services": 
    "hip_replacement": 
      "title": "Hip Replacement",
      "providers": 
        "the_blue_hospital": true,
        "the_red_hospital": true
      
    ,
    ...
  ,
  "providers": 
    "the_blue_hospital": 
      "title": "The Blue Hospital",
    ,
    "the_red_hospital": ...
    ,
    "the_green_hospital": ...
    
  

有没有更好的方法来实现这个或更优雅的解决方案?任何帮助表示赞赏。

提前致谢!

【问题讨论】:

这似乎可行,你当然可以做得更糟:)。您期望每个服务和提供商维度有多少数据?与读取相比,创建/删除操作的执行频率如何? @JamesWing 在每个维度上都有相当数量的数据(10-12),但不超过 2-3 个级别。你为什么要问?如果我要处理大量数据,有没有更好的方法? 我的想法正好相反,让客户端从各种“连接”表中加载所有数据。如果有数百条小记录,那可能是非常可行的。 不确定什么是“join”表,您能详细说明一下吗?计划是让这些维度保持同步。 【参考方案1】:

Firebase 中连接数据的问题在于,您会以牺牲其他用例为代价来优化某些读取或更新用例。在上面的示例中,创建或删除服务和提供者之间的关系需要对每个“表”进行两次单独的更新。这确实没有什么问题,但这不是唯一的方法。

对于规模适中的数据集,您可以有一个将服务映射到提供者的“连接表”,类似于在关系数据库领域中所做的事情。数据可能如下所示:


  "services": 
    "hip_replacement": 
  ,
  "providers": 
    "the_blue_hospital": ...,
    "the_red_hospital": ...,
    "the_green_hospital": ...
  ,
  "serviceProviders": 
    "-JqD5JX0RUDTXsu7Ok3R": 
      "provider": "the_blue_hospital",
      "service": "hip_replacement"
  
    "-JqDoKfyJqPkQlCXDvFM": 
      "provider": "the_green_hospital",
      "service": "hip_replacement"
  
    "-JbE7Ji_JRz2bHgBdMWQ": 
      "provider": "the_blue_hospital",
      "service": "hip_replacement"
  

这种方法有利有弊:

专业版

在一处轻松添加映射 在一处轻松删除映射 在单个提供商或服务(例如索引)的上下文之外重新格式化数据以进行显示的灵活选项。

骗局

您已加载整个数据集。 Firebase 不允许您在键中进行过滤,客户端必须加载整个列表,然后在内存中进行过滤。我怀疑这对于数百条记录都可以正常工作,无论如何,也许对于低数千条记录。 您必须做一些客户端工作来过滤列表以供显示并将其与实际的服务和提供者数据合并。同样,如果数据集不是太大,下划线/lodash groupBy() 可以缩短工作时间。

你应该考虑:

您将进行多少更新和删除? 加盟信息真的那么简单吗?您是否需要更多记录(显示名称、价格等)以使连接表的维护比我建议的更复杂?

【讨论】:

不确定“Firebase 不允许您在没有密钥的情况下进行过滤”是什么意思。你不能简单地做orderByChild('service').equalTo('hip_replacement') 或使用queries 的等效操作吗? 你是对的,当serviceProvider的项目如上图那么简单时,你就可以做到。 抱歉回复晚了。假设我要采用这种方法,是否很难维护providers/services 中的数据和serviceProviders 中的数据之间的更新?假设“the_blue_hospital”改名为“the_sky_blue_hospital”,我还要在两个地方更新吗? 如果关键字段改变了,是的。如果您将其建模为“displayName”或其他非关键字段,则不会。 嗯,你给了我一些思考。这是我第一次尝试这样的事情,我突然意识到数据库的结构应该是优雅的。我想找到最优雅的方法并采用它。

以上是关于在 Firebase 中构建关系的主要内容,如果未能解决你的问题,请参考以下文章

从 RDBMS 的角度构建 Firebase 中的数据

关于 Cocoapods 和 Firebase/Messaging 的 Unity iOS 构建错误

安装 Firebase 后 Flutter 无法在 Android 上运行

无法构建模块 Firebase

在 Xcode 中构建档案时出错(我使用过 Unity 和 Firebase)

在 Firebase 中构建聊天应用程序的数据