firebase
데이터 구조화
수색…
소개
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과 같은 쿼리가 필요한 대부분의 시나리오에서는 일반적으로 데이터를 반전하고 양방향 관계를 만드는 것이 해결책입니다.
위의 데이터베이스를 사용하는 응용 프로그램에서 다음을 수행 할 수 있어야합니다.
- 특정 학생이 복용 하고 있는 코스 목록 ...
- 특정 과목의 모든 학생들을 나열하십시오.
데이터베이스 구조가 단방향이라면 위의 두 가지 요구 사항 중 하나를 스캔하거나 쿼리하는 데 엄청나게 느려질 것입니다. 일부 시나리오에서는 중복성으로 인해 빈번한 운영이 더 빠르고 효율적으로 이루어지기 때문에 장기적으로 복제 비용은 무시할 수 있습니다.