firebase
Strutturazione dei dati
Ricerca…
introduzione
Il database Firebase è un database NoSQL che memorizza i suoi dati sotto forma di oggetti JSON gerarchici. Non ci sono tabelle o record di qualsiasi forma come normalmente dovrebbe avere un database SQL, solo nodi che costituiscono una struttura di valori-chiave.
Normalizzazione dei dati
Per avere una struttura di database correttamente progettata, i requisiti dei dati devono essere accuratamente delineati e preveggenti. La struttura in questo caso dovrebbe essere normalizzata; più piatto è l'albero JSON, più veloce è l'accesso ai dati.
Cosa fare e cosa non fare
La strada sbagliata
Considera la seguente struttura
{
"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
}
}
Questo è un ottimo esempio di cosa NON fare. Strutture multi-nidificate come quella sopra possono essere molto problematiche e causare un enorme calo delle prestazioni.
Il modo in cui Firebase accede a un nodo è il download di tutti i dati dei bambini, quindi l'iterazione su tutti i nodi dello stesso livello (i figli di tutti i genitori). Ora immagina un database con diversi utenti , ognuno con centinaia (o anche migliaia) di post . L'accesso a un post in questo caso potrebbe potenzialmente caricare centinaia di megabyte di dati inutilizzati. In un'applicazione più complicata, il nesting potrebbe essere più profondo di solo 4 livelli, il che comporterebbe download e iterazioni più inutili.
Il modo giusto
Appiattire la stessa struttura sarebbe come questo
{
// "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
}
}
Ciò risparmia una quantità enorme di overhead iterando su meno nodi per accedere a un oggetto target. Tutti gli utenti che non hanno alcun post non esisterebbero nel ramo dei post e quindi iterare sopra quegli utenti nel modo sbagliato sopra è completamente inutile.
Relazioni a due vie
Quello che segue è un esempio di un database college semplice e minimale che utilizza relazioni a due vie
{
"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
}
}
Nota che ogni studente ha un elenco di corsi e ogni corso ha un elenco di studenti iscritti.
La ridondanza non è sempre un approccio sbagliato. È vero che costa lo spazio di archiviazione e deve gestire l'aggiornamento di più voci durante l'eliminazione o la modifica di un nodo duplicato; tuttavia, in alcuni scenari in cui i dati non vengono aggiornati spesso, la presenza di relazioni a due vie potrebbe facilitare notevolmente il processo di recupero / scrittura.
Nella maggior parte degli scenari in cui sembra necessaria una query simile a SQL, l'inversione dei dati e la creazione di relazioni bidirezionali sono solitamente la soluzione.
Prendi in considerazione un'applicazione che utilizza il database precedente che richiede la capacità di:
- Elenca i corsi che un certo studente sta prendendo e ...
- Elenca tutti gli studenti in un certo corso
Se la struttura del database fosse stata unidirezionale, sarebbe stato incredibilmente più lento scansionare o interrogare per uno dei due requisiti precedenti. In alcuni scenari, la ridondanza rende le operazioni frequenti più veloci e molto più efficienti che, a lungo termine, riducono il costo delle duplicazioni.