我对基于Firestore的项目的结构有些担心,因为直接嵌套文档似乎不是一种选择。
为简单起见,假设我们有一个Firestore数据库,其中包含有关足球比赛的数据。对于每场比赛,都有一个包含球员阵容的文件,一个包含比赛事件列表的文件,一个包含比赛统计信息的文件等。
由于统计信息,事件和阵容等信息是在不同的时间间隔更新,从不同的API调用导入并在使用应用程序的单独屏幕中使用的,因此我认为将它们保存在单独的文档中是最明智的做法。
我目前正在使用这样的结构:
/app-data/match-lineup/matches/123456
/app-data/match-events/matches/123456
/app-data/match-statistics/matches/123456
然后我这样指代它:
db.collection("app-data")
.doc("match-lineups")
.collection("matches")
.doc(id);
但是当我添加与比赛相关的更多不同文档时,我开始担心当前结构是否为反模式。
我更喜欢这样的结构,我发现它最优雅,并且与REST URL相似。
/matches/123456/lineup
但这不是一个选择,因为123456
无法引用lineup
文档。
解决方法可能类似于
/matches/123456/attributes/lineup
带有这样的参考
db.collection("matches")
.doc(id);
.collection("attributes")
.doc("lineup")
这是最好的折衷方案,还是应该考虑其他选择?
答案 0 :(得分:2)
在NoSQL数据库中对数据建模时,永远不会有最佳和独特解决方案。
恕我直言,您的两种方法是完全有效的,因为每个集合中包含的数据都将“在使用中的应用程序的单独屏幕中使用”(即,没有理由将所有数据“集中”在一个文档中,正如您提到的)。在查询效率方面,两种方法相似。
但是,您可能还要考虑其他条件:(在撰写本文时)您不能查询跨馆藏。当您需要查询所有比赛时,例如在阵容中与特定球员的所有比赛或与eventType == "penalty"
的所有比赛时,您可能会遇到用例。在这种情况下,您应该使用方法#1(即/app-data/match-lineup/matches/123456
),因为使用方法#2不可能在匹配项中进行此类查询。