Firebase中的多对多关系

我有一个Firebase数据库。 我有公司和承包商。 承包商可以为多个公司工作,而公司可以有多个承包商。 这是一个直截了当的多对多的关系。 我希望能够回答有关公司和承包商的问题:

  1. 给定一个公司,谁是目前的承包商。
  2. 给承包商什么公司他们的工作。

在Firebase中构build数据有哪些select?

自我回答确实是对此进行build模的一种方式。 这可能是如何在关系数据库中build模的最直接的等价物:

  • 承包商
  • 公司
  • companyAndContractorsAssignment(多对多连接器表)

另一种方法是使用4个顶级节点:

  • 承包商
  • 公司
  • companyContractors
  • contractorCompanies

最后两个节点看起来像:

companyContractors companyKey1 contractorKey1: true contractorKey3: true companyKey2 contractorKey2: true contractorCompanies contractorKey1 companyKey1: true contractorKey2 companyKey2: true contractorKey3 companyKey1: true 

这种双向结构使您既能够查找“公司的承包商”和“承包商的公司”,也不需要查询这些结果。 这一定会更快,特别是当你增加承包商和公司。

这对于您的应用程序是否有必要取决于您所需的用例,您期望的数据大小等等。

推荐阅读NoSQL数据build模和查看适用于SQL开发人员的Firebase 。 这个问题也出现在#AskFirebase youtube系列剧集中 。

更新(2017016)

有人发布了一个后续的问题,这里有关于检索“承包商”和“公司”节点的实际项目的链接 。 您将需要一次检索那些,因为Firebase没有等同于SELECT * FROM table WHERE id IN (1,2,3) 。 但是这个操作并没有你想象的那么慢,因为这些请求是通过一个连接stream水线化的。 阅读更多关于这里: 加快通过使用查询而不是重复观察单个事件为我的社交networking应用获取post 。

经过进一步的研究,我会试着回答我自己的问题。 我已经回顾了其他一些post,一对多问题的解决scheme是在公司对象中存储一个ContractorKeys列表,并在每个Contractor对象中存储一个CompanyKeys列表。 下面举例说明。

 companies : { companyKey1 : { name : company1 ... contractors : { contractorKey1 : true, contractorKey3 : true } } companyKey2 : { name : company2 ... contractors : { contractorKey2 : true, } } } contrators : { contractorKey1 : { name : bill ... companies : { companyKey1 : true } } contractorKey2 : { name : steve ... companies : { companyKey1 : true } } contractorKey3 : { name : jim ... companies : { companyKey2 : true } } } 

这个组织“运作”的意义在于上述问题是可以回答的。 但是这个解决scheme的缺点是,当承包商/公司的任务改变时,有两个清单需要维护。 如果有一种方法可以将这些信息表示在一个列表中,那将会更好。

我想我已经想出了一个更好的解决scheme。 解决scheme是创build第三个列表,除了公司和承包商称为companyAndContractorAssignment。 这个清单的元素将代表一个承包商和公司之间的关系。 其内容将是一对字段,contractorKey和companyKey。 然后,我们可以删除公司内的承包商名单和承包商的公司名单。 下面介绍这种替代结构。 请注意,公司对象中没有承包商列表,也没有公司列出承包商对象。

 companies : { companyKey1 : { name : company1 ... } companyKey2 : { name : company2 ... } } contrators : { contractorKey1 : { name : bill ... } contractorKey2 : { name : steve ... } contractorKey3 : { name : jim ... } } companyAndContractorsAssignment : { key1 : { contractorKey1 : true, companyKey1: true, } key2 : { contractorKey3 : true, companyKey1: true, } key3 : { contractorKey2 : true, companyKey2: true, } 

这种替代结构允许人们使用companyAndContractorsAssignment的orderByChild / equalTo查询来回答问题,以find承包商的所有公司或公司的所有承包商。 现在只有一个列表需要维护。 我认为这是我的要求的最佳解决scheme。