Как обрабатывать иерархические данные в Firebase?

#firebase #firebase-realtime-database #hierarchical-data #nosql

#firebase #firebase-база данных в реальном времени #иерархические-данные #nosql

Вопрос:

Я создаю приложение с использованием Firebase, и у меня возникают проблемы со структурированием данных для иерархии, которая нужна моему приложению.

Концепция

Мое приложение состоит из items . Каждый элемент может иметь n -много child items . В базе данных и для любого заданного элемента будет 100 тысяч элементов. Я хочу получить количество всех дочерних элементов (т. Е. Прямых детей, внуков, правнуков и т. Д.).

Пример текущей структуры

 items: { 
   1: {
       name: 'neat item 1'
   },
   2: {
       name: 'neat item 2',
       parentId: 1
   },
   3: {
       name: 'neat item 3',
       parentId: 2
   }
}
  

Вопрос

Каков наилучший способ отслеживания количества дочерних элементов в Firebase? Итак, в приведенном выше примере элемент # 1 имеет всего 2 дочерних элемента, элемент # 2 имеет всего 1 дочерний элемент.

Было бы лучше поддерживать a childCount для каждого элемента и всякий раз, когда добавляется новый элемент, увеличивать это число для всех родителей? Или было бы лучше рекурсивно вычислять количество дочерних элементов всякий раз, когда это необходимо?

Имейте в виду, что в базе данных будет более 500 000 элементов, а некоторые элементы будут иметь в общей сложности более 10 000 дочерних элементов.

Большое спасибо за ваше время!

Ответ №1:

В Firebase (как и в большинстве баз данных NoSQL) вы должны моделировать данные так, как их использует ваше приложение (я настоятельно рекомендую прочитать эту статью о моделировании данных NoSQL для получения дополнительной информации).

Важно понимать, что Firebase всегда загружает весь узел, включая все данные под этим узлом. Нет способа (в SDK) загружать так называемые мелкие данные.

Итак, если ваше приложение всегда показывает все дерево целиком, вы определенно можете моделировать данные как дерево.

Но, учитывая размер дерева, гораздо более вероятно, что вы собираетесь показывать по одному уровню за раз, а затем позволять пользователю нажимать, чтобы развернуть этот уровень. Если бы вы моделировали данные как иерархию, вы бы в конечном итоге загрузили все дочерние элементы узла, даже если пользователь никогда не расширяет этот узел. Это расточительно.

Поэтому более распространенным является сохранение иерархии в виде списка, очень похожего на то, как вы храните его в реляционной базе данных. Затем вы бы сохранили отдельный список дочерних элементов каждого узла. Обратите внимание, что это список, а не дерево.

 nodes
  nodeKey1
    name: "Node 1"
    childrenCount: 2
  nodeKey2
    name: "Node 2"
    childrenCount: 1
    parentKey: "nodeKey1"
  nodeKey3
    name: "Node 3"
    childrenCount: 0
    parentKey: "nodeKey1"
  nodeKey4
    name: "Node 4"
    childrenCount: 0
    parentKey: "nodeKey2"
nodeChildren
  nodeKey1
    nodeKey2
    nodeKey3
  nodeKey2
    nodeKey4
  

Это позволяет эффективно считывать / запрашивать:

  • список узлов верхнего уровня ( ref.orderByChild('parentNode').equalTo(null) )
  • метаданные для определенного узла
  • родительский элемент определенного узла
  • дочерние элементы определенного узла

Если у вас больше вариантов использования, вам может потребоваться расширить модель данных.

Комментарии:

1. Большое спасибо за быстрый ответ! Это то, о чем я думал, но меня беспокоит, как получить «totalChildCount» для любого заданного элемента. В вашем примере «childrenCount» только для прямых дочерних элементов или это будет для всех дочерних элементов? В любом случае, мне интересно, как лучше всего эффективно рассчитать totalChildCount для данного элемента (если он должен устанавливаться / увеличиваться при добавлении элемента или если он должен вычисляться при извлечении элемента. Примечание: вы правы в том, что мне не нужны все дочерние элементы одновременно, просто прямые дочерние элементы и «общее количество дочерних элементов» Еще раз спасибо!!