Ответ 1
Если у вас есть пользователи и комментарии, вы можете легко моделировать их следующим образом:
ROOT
|
+-- vzhen
| |
| +-- Vzhen comment 1
| |
| +-- Vzhen comment 2
|
+-- Frank van Puffelen
|
+-- Frank comment 1
|
+-- Frank comment 2
Однако более вероятно, что существует третий объект, такой как статья, и что пользователи комментируют статьи (друг друга).
Firebase не имеет понятия внешнего ключа, но его легко имитировать. Если вы это сделаете, вы можете моделировать структуру user/article/comment следующим образом:
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 comment on Article 1 (CID=1)
| |
| +-- Frank response (CID=2)
| |
| +-- Frank 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)
Это довольно прямое сопоставление того, как вы моделируете это в реляционной базе данных. Основная проблема с этой моделью - это количество поисков, которые вам понадобятся для получения необходимой информации для одного экрана.
- Прочитайте статью (из статьи СТАТЬИ node)
- Прочитайте информацию о комментариях (из ARTICLE_USER_COMMENT node)
- Прочитайте содержание комментариев (из КОММЕНТАРИИ node)
В зависимости от ваших потребностей вам может потребоваться также прочитать ПОЛЬЗОВАТЕЛИ node.
И имейте в виду, что Firebase не имеет понятия предложения WHERE, которое позволяет вам выбирать только элементы из ARTICLE_USER_COMMENT, которые соответствуют определенной статье или конкретному пользователю.
На практике такой способ отображения структуры неприменим. Firebase - это иерархическая структура данных, поэтому мы должны использовать уникальные способности, которые дают нам более традиционную реляционную модель. Например: нам не нужен ARTICLE_USER_COMMENT node, мы можем просто хранить эту информацию непосредственно под каждой статьей, пользователем и самим комментарием.
Небольшой фрагмент этого:
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 comment on Article 1 (CID=1)
|
+-- Frank response (CID=2)
|
+-- Frank comment on article 2 (CID=3)
Здесь вы можете видеть, что мы распространяем информацию из ARTICLE_USER_COMMENT над статьей и пользовательскими узлами. Это немного денормализует данные. В результате нам нужно будет обновить несколько узлов, когда пользователь добавит комментарий к статье. В приведенном выше примере нам нужно будет добавить сам комментарий, а затем узлы к соответствующему пользователю node и статье node. Преимущество состоит в том, что у нас меньше узлов для чтения, когда нам нужно отображать данные.
Если вы сделаете эту денормализацию наиболее экстремальной, вы получите такую структуру данных, как это:
ROOT
|
+-- ARTICLES
| |
| +-- Text of article 1 (AID=1)
| | |
| | +-- Vzhen comment on Article 1 (UID=1056201)
| | |
| | +-- Frank response (UID=209103)
| |
| +-- Text of article 2 (AID=2)
| |
| +-- Frank comment on Article 2 (UID=209103)
|
+-- USERS
|
+-- vzhen (UID=1056201)
| |
| +-- Vzhen comment on Article 1 (AID=1)
|
+-- Frank van Puffelen (UID=209103)
|
+-- Frank response (AID=1)
|
+-- Frank comment on Article 2 (AID=2)
Вы можете видеть, что мы избавились от узлов COMMENTS и ARTICLE_USER_COMMENT в этом последнем примере. Вся информация о статье теперь хранится непосредственно в самой статье node, включая комментарии к этой статье (с "ссылкой" на пользователя, который сделал комментарий). И вся информация о пользователе теперь сохраняется под этим пользователем node, включая комментарии, сделанные пользователем (с "ссылкой" на статью, о которой идет комментарий).
Единственная вещь, которая по-прежнему сложна в этой модели, заключается в том, что Firebase не имеет API для прохождения таких "ссылок", поэтому вам придется искать пользователя/статью самостоятельно. Это становится намного проще, если вы используете UID/AID (в этом примере) в качестве имени node, который идентифицирует пользователя/статью.
Итак, это приводит к нашей окончательной модели:
ROOT
|
+-- ARTICLES
| |
| +-- AID_1
| | |
| | +-- Text of article 1
| | |
| | +-- COMMENTS
| | |
| | +-- Vzhen comment on Article 1 (UID=1056201)
| | |
| | +-- Frank response (UID=209103)
| |
| +-- AID_2
| |
| +-- Text of article 2
| |
| +-- COMMENTS
| |
| +-- Frank comment on Article 2 (UID=209103)
|
+-- USERS
|
+-- UID_1056201
| |
| +-- vzhen
| |
| +-- COMMENTS
| |
| +-- Vzhen comment on Article 1 (AID=1)
|
+-- UID_209103
|
+-- Frank van Puffelen
|
+-- COMMENTS
|
+-- Frank response (AID=1)
|
+-- Frank comment on Article 2 (AID=2)
Я надеюсь, что это поможет понять иерархическое моделирование данных и связанные с ними компромиссы.