Поиск…


Вступление

База данных 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-подобный запрос, инвертирование данных и создание двусторонних отношений обычно являются решением.

Рассмотрите приложение, использующее базу данных выше, которая требует возможности:

  1. Перечислите курсы, которые принимает определенный студент, и ...
  2. Список всех студентов в определенном курсе

Если структура базы данных была однонаправленной, было бы невероятно медленнее сканировать или запрашивать одно из двух вышеуказанных требований. В некоторых сценариях избыточность делает частые операции более быстрыми и намного более эффективными, что в конечном счете делает стоимость дублирования незначительной.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow