Firebase中的多对多关系

Rob*_*man 33 nosql firebase firebase-realtime-database angularfire2

我有一个Firebase数据库.我有公司和承包商.承包商可以为多个公司工作,公司可以拥有多个承包商.这是一个简单的多对多关系.我希望能够回答有关公司和承包商的问题:

  1. 鉴于一家公司,谁是现有的承包商.
  2. 鉴于承包商他们为公司工作的是什么.

在firebase中构建数据的替代方法有哪些?

Fra*_*len 26

自我答案确实是对此进行建模的一种方式.它可能是你在关系数据库中如何建模的最直接的等价物:

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

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

  • 承包商
  • 公司
  • companyContractors
  • contractorCompanies

最后两个节点看起来像:

companyContractors
    companyKey1
        contractorKey1: true
        contractorKey3: true
    companyKey2
        contractorKey2: true
contractorCompanies
    contractorKey1
        companyKey1: true
    contractorKey2
        companyKey2: true
    contractorKey3
        companyKey1: true
Run Code Online (Sandbox Code Playgroud)

这种双向结构允许您查找"公司的承包商"和"承包商的公司",而这些都不需要查询.这必然会更快,特别是在您添加承包商和公司时.

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

推荐阅读NoSQL数据建模和查看Firebase for SQL开发人员.这个问题也出现在#AskFirebase youtube系列的集中.

更新(2017016)

有人发布了一个后续问题,该问题链接到这里从"承包商"和"公司"节点检索实际项目.您需要一次检索一个,因为Firebase没有等效的SELECT * FROM table WHERE id IN (1,2,3).但是这个操作并不像你想象的那么慢,因为请求是通过单个连接进行流水线操作的.在此处阅读更多相关信息:通过使用查询而不是反复观察单个事件,加快为我的社交网络应用程序提取帖子.

  • 有没有什么方法可以使用.validation或.write规则来验证这些值。...即,承包商不应包含不存在的companyKey。 (2认同)

Rob*_*man 5

经过进一步的研究,我将尝试回答我自己的问题.我已经审查了许多其他帖子,并且对多对多问题的解决方案是在公司对象中存储ContractorKeys列表并在每个承包商对象中存储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
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

从可以回答上述问题的意义上讲,该组织"有效".但该解决方案的缺点是,当承包商/公司的分配发生变化时,有两个列表需要维护.如果有一种方法可以在一个列表中表示这些信息,那就更好了.

我想我已经想出了一个更好的解决方案.解决方案是创建第三个列表,此外还有名为companyAndContractorAssignment的公司和承包商.此列表的元素将代表单个承包商与公司之间的关系.它的内容将是一对领域,承包商密钥和公司密钥.然后我们可以取消公司内的承包商名单和承包商内的公司名单.该替代结构如下所示.请注意,公司对象中没有承包商列表,也没有公司列出承包商对象.

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,
  }
Run Code Online (Sandbox Code Playgroud)

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

  • 我想如果你这样做,你可能会在索引方面遇到性能问题.Firebase会要求您在orderByChild上执行indexOn,但由于这些是动态密钥,因此可能会变成一个需要维护的噩梦. (2认同)

归档时间:

查看次数:

10578 次

最近记录:

8 年,6 月 前