firebase
Struktura danych
Szukaj…
Wprowadzenie
Baza danych Firebase to baza danych NoSQL, która przechowuje swoje dane w postaci hierarchicznych obiektów JSON. Nie ma żadnych tabel ani rekordów w jakiejkolwiek formie, jaką normalnie posiadałaby baza danych SQL, tylko węzły tworzące strukturę klucz-wartość.
Normalizacja danych
Aby mieć właściwie zaprojektowaną strukturę bazy danych, wymagania dotyczące danych muszą być dokładnie określone i przemyślane. Struktura w tym przypadku powinna zostać znormalizowana; im bardziej płaskie drzewo JSON, tym szybszy dostęp do danych.
Za I przeciw
Zły kierunek
Rozważ następującą strukturę
{
"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
}
}
To świetny przykład tego, czego NIE należy robić. Struktury wielo zagnieżdżone, takie jak powyższa, mogą być bardzo problematyczne i mogą powodować ogromne pogorszenie wydajności.
Sposób, w jaki Firebase uzyskuje dostęp do węzła, polega na pobraniu wszystkich danych dzieci, a następnie iteracji po wszystkich węzłach tego samego poziomu (dzieci wszystkich rodziców). Teraz wyobraź sobie bazę danych z kilkoma użytkownikami , z których każdy ma setki (a nawet tysiące) postów . Dostęp do postu w tym przypadku może potencjalnie załadować setki megabajtów nieużywanych danych. W bardziej skomplikowanej aplikacji zagnieżdżanie może być głębsze niż tylko 4 warstwy, co spowodowałoby więcej bezużytecznych pobrań i iteracji.
Właściwy sposób
Spłaszczenie tej samej struktury wyglądałoby tak
{
// "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
}
}
Oszczędza to ogromnego nakładu pracy, iterując mniejszą liczbę węzłów, aby uzyskać dostęp do obiektu docelowego. Wszyscy użytkownicy , którzy nie mają żadnych postów, nie będą istnieć w gałęzi postów , więc iteracja nad tymi użytkownikami w niewłaściwy sposób powyżej jest całkowicie bezużyteczna.
Relacje dwukierunkowe
Poniżej znajduje się przykład prostej i minimalnej bazy danych uczelni, która wykorzystuje dwustronne relacje
{
"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
}
}
Pamiętaj, że każdy uczeń ma listę kursów i każdy kurs ma listę zapisanych studentów .
Redundancja nie zawsze jest złym podejściem. Prawdą jest, że to kosztuje przestrzeń dyskową i konieczność radzenia sobie z aktualizacją wielu wpisów podczas usuwania lub edycji zduplikowanego węzła; jednak w niektórych scenariuszach, w których dane nie są często aktualizowane, wzajemne relacje mogą znacznie ułatwić proces pobierania / zapisywania.
W większości scenariuszy, w których wydaje się potrzebne zapytanie podobne do SQL, zwykle rozwiązaniem jest odwrócenie danych i utworzenie dwustronnych relacji.
Rozważ aplikację korzystającą z powyższej bazy danych, która wymaga umiejętności:
- Wymień kursy, które bierze dany uczeń i ...
- Wymień wszystkich uczniów na danym kursie
Gdyby struktura bazy danych była jednokierunkowa, skanowanie lub wyszukiwanie jednego z dwóch powyższych wymagań byłoby znacznie wolniejsze. W niektórych scenariuszach nadmiarowość sprawia, że częste operacje są szybsze i znacznie wydajniejsze, co w dłuższej perspektywie sprawia, że koszt duplikacji jest znikomy.