如果你有用户和 cmets,你可以像这样轻松地建模:
ROOT
|
+-- vzhen
| |
| +-- Vzhen's comment 1
| |
| +-- Vzhen's comment 2
|
+-- Frank van Puffelen
|
+-- Frank's comment 1
|
+-- Frank's comment 2
但是,更有可能存在第三方实体,例如文章,并且用户正在评论(彼此的)文章。
Firebase 没有外键的概念,但很容易模仿。如果这样做,您可以像这样对用户/文章/评论结构进行建模:
ROOT
|
+-- ARTICLES
| |
| +-- Text of article 1 (AID=1)
| |
| +-- Text of article 2 (AID=2)
|
+-- USERS
| |
| +-- vzhen (UID=1056201)
| |
| +-- Frank van Puffelen (UID=209103)
|
+-- COMMENTS
| |
| +-- Vzhen's comment on Article 1 (CID=1)
| |
| +-- Frank's response (CID=2)
| |
| +-- Frank's comment on article 2 (AID=2,UID=209103)
|
+-- ARTICLE_USER_COMMENT
|
+-- (AID=1,UID=1056201,CID=1)
|
+-- (AID=1,UID=209103,CID=2)
|
+-- (AID=2,UID=209103,CID=3)
这是您在关系数据库中建模的方式的一个非常直接的映射。此模型的主要问题是您需要进行多次查找才能获取单个屏幕所需的信息。
- 阅读文章本身(来自 ARTICLES 节点)
- 读取有关 cmets 的信息(来自 ARTICLE_USER_COMMENT 节点)
- 读取 cmets 的内容(从 COMMENTS 节点)
根据您的需要,您甚至可能还需要读取 USERS 节点。
请记住,Firebase 没有 WHERE 子句的概念,该子句允许您从 ARTICLE_USER_COMMENT 中仅选择与特定文章或特定用户匹配的元素。
在实践中,这种映射结构的方式是不可用的。 Firebase 是一种分层数据结构,因此我们应该使用为我们提供的独特功能,而不是更传统的关系模型。例如:我们不需要 ARTICLE_USER_COMMENT 节点,我们可以直接在每篇文章、用户和评论本身下保存这些信息。
这个小sn-p:
ROOT
|
+-- ARTICLES
| |
| +-- Text of article 1 (AID=1)
| . |
| . +-- (CID=1,UID=1056201)
| . |
| +-- (CID=2,UID=209103)
|
+-- USERS
| |
| +-- vzhen (UID=1056201)
| . |
| . +-- (AID=1,CID=1)
| .
|
+-- COMMENTS
|
+-- Vzhen's comment on Article 1 (CID=1)
|
+-- Frank's response (CID=2)
|
+-- Frank's comment on article 2 (CID=3)
您可以在此处看到,我们正在将来自 ARTICLE_USER_COMMENT 的信息传播到文章和用户节点。这有点对数据进行非规范化。结果是当用户向文章添加评论时,我们需要更新多个节点。在上面的示例中,我们必须添加评论本身,然后将节点添加到相关的用户节点和文章节点。好处是当我们需要显示数据时,我们可以读取的节点更少。
如果你将这种非规范化发挥到极致,你最终会得到这样的数据结构:
ROOT
|
+-- ARTICLES
| |
| +-- Text of article 1 (AID=1)
| | |
| | +-- Vzhen's comment on Article 1 (UID=1056201)
| | |
| | +-- Frank's response (UID=209103)
| |
| +-- Text of article 2 (AID=2)
| |
| +-- Frank's comment on Article 2 (UID=209103)
|
+-- USERS
|
+-- vzhen (UID=1056201)
| |
| +-- Vzhen's comment on Article 1 (AID=1)
|
+-- Frank van Puffelen (UID=209103)
|
+-- Frank's response (AID=1)
|
+-- Frank's comment on Article 2 (AID=2)
您可以看到我们在最后一个示例中删除了 COMMENTS 和 ARTICLE_USER_COMMENT 节点。现在,关于一篇文章的所有信息都直接存储在文章节点本身下,包括该文章的 cmets(带有指向发表评论的用户的“链接”)。现在,关于用户的所有信息都存储在该用户的节点下,包括用户创建的 cmets(带有指向评论所涉及文章的“链接”)。
这个模型唯一仍然棘手的是 Firebase 没有 API 来遍历此类“链接”,因此您必须自己查找用户/文章。如果您使用 UID/AID(在此示例中)作为标识用户/文章的节点名称,这将变得容易得多。
这就是我们的最终模型:
ROOT
|
+-- ARTICLES
| |
| +-- AID_1
| | |
| | +-- Text of article 1
| | |
| | +-- COMMENTS
| | |
| | +-- Vzhen's comment on Article 1 (UID=1056201)
| | |
| | +-- Frank's response (UID=209103)
| |
| +-- AID_2
| |
| +-- Text of article 2
| |
| +-- COMMENTS
| |
| +-- Frank's comment on Article 2 (UID=209103)
|
+-- USERS
|
+-- UID_1056201
| |
| +-- vzhen
| |
| +-- COMMENTS
| |
| +-- Vzhen's comment on Article 1 (AID=1)
|
+-- UID_209103
|
+-- Frank van Puffelen
|
+-- COMMENTS
|
+-- Frank's response (AID=1)
|
+-- Frank's comment on Article 2 (AID=2)
我希望这有助于理解分层数据建模和所涉及的权衡。