我有一个Firebase数据库。我有公司和承包商。承包商可以为多个公司工作,公司可以拥有多个承包商。这是一个简单的多对多关系。我希望能够回答有关公司和承包商的问题:
在firebase中构建数据有哪些替代方法?
答案 0 :(得分:25)
自我答案确实是建模的一种方式。它可能是你在关系数据库中如何建模的最直接的等价物:
另一种方法是使用4个顶级节点:
最后两个节点如下:
companyContractors
companyKey1
contractorKey1: true
contractorKey3: true
companyKey2
contractorKey2: true
contractorCompanies
contractorKey1
companyKey1: true
contractorKey2
companyKey2: true
contractorKey3
companyKey1: true
这种双向结构允许您查找“公司的承包商”和“承包商的公司”,而不需要查询任何一个。这必然会更快,特别是在您添加承包商和公司时。
这是否是您的应用所必需的,取决于您需要的用例,您期望的数据大小等等。
建议阅读NoSQL data modeling并查看Firebase for SQL developers。这个问题也出现在episode of the #AskFirebase youtube series。
中有人发布了follow-up question that links here关于从“承包商”和“公司”节点检索实际项目的信息。您需要一次检索一个,因为Firebase没有等效的SELECT * FROM table WHERE id IN (1,2,3)
。但是这个操作并不像你想象的那么慢,因为请求是通过单个连接进行流水线操作的。在此处详细了解:Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly。
答案 1 :(得分: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
}
}
}
该组织“有效”,可以回答上述问题。但该解决方案的缺点是,当承包商/公司的分配发生变化时,有两个列表需要维护。如果有一种方法可以在一个列表中表示这些信息,那就更好了。
我想我已经想出了一个更好的解决方案。解决方案是创建第三个列表,此外还有名为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,
}
这种替代结构允许人们使用companyAndContractorsAssignment上的orderByChild / equalTo查询来回答问题,以找到承包商的所有公司或公司的所有承包商。现在只有一个列表需要维护。我认为这是满足我要求的最佳解决方案。