수색…


소개

Firebase 데이터베이스는 데이터를 계층 적 JSON 객체 형식으로 저장하는 NoSQL 데이터베이스입니다. 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
  }
}

이렇게하면 적은 노드를 반복하여 대상 객체에 액세스하여 엄청난 오버 헤드를 방지 할 수 있습니다. 게시물이없는 모든 사용자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