#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 для данного элемента (если он должен устанавливаться / увеличиваться при добавлении элемента или если он должен вычисляться при извлечении элемента. Примечание: вы правы в том, что мне не нужны все дочерние элементы одновременно, просто прямые дочерние элементы и «общее количество дочерних элементов» Еще раз спасибо!!