firebase
Структурирование данных
Поиск…
Вступление
База данных Firebase представляет собой базу данных NoSQL, которая хранит свои данные в виде иерархических объектов JSON. Нет таблиц или записей какой-либо формы, как обычно в базе данных SQL, только узлы, которые составляют структуру значений ключа.
Нормализация данных
Чтобы иметь должным образом спроектированную структуру базы данных, требования к данным должны быть тщательно очерчены и предусмотрительно. Структура в этом случае должна быть нормирована; чем больше плоское дерево JSON, тем быстрее доступ к данным.
Делайте и не делайте
Неправильный путь
Рассмотрим следующую структуру
{
"users": {
// Uniquely generated IDs for children is common practice,
// it's actually really useful for automating child creation.
// Auto-incrementing an integer for a key can be problematic when a child is removed.
"-KH3Cx0KFvSQELIYZezv": {
"name": "Jon Snow",
"aboutMe": "I know nothing...",
"posts": {
"post1": {
"body": "Different roads sometimes leads to the same castle",
"isHidden": false
},
"post2": { ... },
// Possibly more posts
}
},
"-KH3Dx2KFdSLErIYZcgk": { ... }, // Another user
// A lot more users here
}
}
Это отличный пример того, что НЕ делать. Многослойные структуры, такие как выше, могут быть очень проблематичными и могут привести к огромному снижению производительности.
Способ доступа Firebase к узлу - это загрузка всех данных для детей, а затем повторение всех узлов одного уровня (всех родителей). Теперь представьте себе базу данных с несколькими пользователями , каждая из которых имеет сотни (или даже тысячи) сообщений . Доступ к сообщению в этом случае может потенциально загрузить сотни мегабайт неиспользуемых данных. В более сложном приложении вложенность может быть более глубокой, чем всего 4 слоя, что приведет к более бесполезным загрузкам и итерациям.
Правильный путь
Сглаживание той же структуры будет выглядеть так
{
// "users" should not contain any of the posts' data
"users": {
"-KH3Cx0KFvSQELIYZezv": {
"name": "Jon Snow",
"aboutMe": "I know nothing..."
},
"-KH3Dx2KFdSLErIYZcgk": { ... },
// More users
},
// Posts can be accessed provided a user key
"posts": {
"-KH3Cx0KFvSQELIYZezv": { // Jon Snow's posts
"post1": {
"body": "Different roads sometimes leads to the same castle",
"isHidden": false
},
"post2": { ... },
// Possibly more posts
},
"-KH3Dx2KFdSLErIYZcgk": { ... },
// other users' posts
}
}
Это избавляет от огромного количества накладных расходов, повторяя меньшее количество узлов для доступа к целевому объекту. Все пользователи , у которых нет каких-либо сообщений, не будут существовать в ветви сообщений , и поэтому повторение этих пользователей неверно выше полностью бесполезно.
Двусторонние отношения
Ниже приведен пример простой и минимальной базы данных колледжа, которая использует двусторонние отношения
{
"students": {
"-SL3Cs0KFvDMQLIYZEzv": {
"name": "Godric Gryffindor",
"id": "900130309",
"courses": {
"potions": true,
"charms": true,
"transfiguration": true,
}
},
"-SL3ws2KvZQLTYMqzSas": {
"name": "Salazar Slytherin",
"id": "900132319",
"courses": {
"potions": true,
"herbs": true,
"muggleStudies": true,
}
},
"-SL3ns2OtARSTUMywqWt": { ... },
// More students here
},
"courses": {
"potions": {
"code": "CHEM305",
"enrolledStudents": {
"-SL3Cs0KFvDMQLIYZEzv": true, // Godric Gryffindor
"-SL3ws2KvZQLTYMqzSas": true, // Salazar Slytherin
// More students
}
},
"muggleStuddies": {
"code": "SOC215",
"enrolledStudents": {
"-SL3ws2KvZQLTYMqzSas": true, // Salazar Slytherin
"-SL3ns2OtARSTUMywqWt": true, // Some other student
// More students
}
},
// More courses
}
}
Обратите внимание, что у каждого ученика есть список курсов, и у каждого курса есть список зарегистрированных студентов .
Избыточность - это не всегда плохой подход. Это правда, что он требует пространства для хранения и имеет дело с обновлением нескольких записей при удалении или редактировании дублированного узла; однако в некоторых сценариях, где данные не обновляются часто, наличие двухсторонних отношений может значительно облегчить процесс получения / записи.
В большинстве сценариев, где нужен SQL-подобный запрос, инвертирование данных и создание двусторонних отношений обычно являются решением.
Рассмотрите приложение, использующее базу данных выше, которая требует возможности:
- Перечислите курсы, которые принимает определенный студент, и ...
- Список всех студентов в определенном курсе
Если структура базы данных была однонаправленной, было бы невероятно медленнее сканировать или запрашивать одно из двух вышеуказанных требований. В некоторых сценариях избыточность делает частые операции более быстрыми и намного более эффективными, что в конечном счете делает стоимость дублирования незначительной.