firebase
Gegevens structureren
Zoeken…
Invoering
Firebase-database is een NoSQL-database die zijn gegevens opslaat in de vorm van hiërarchische JSON-objecten. Er zijn geen tabellen of records van welke vorm dan ook die een SQL-database normaal zou hebben, alleen knooppunten die een sleutel / waardestructuur vormen.
Gegevensnormalisatie
Om een goed ontworpen databasestructuur te hebben, moeten de gegevensvereisten grondig worden beschreven en doordacht. De structuur moet in dit geval worden genormaliseerd; hoe vlakker de JSON-structuur, hoe sneller gegevenstoegang is.
Wat te doen en wat niet te doen
De verkeerde manier
Overweeg de volgende structuur
{
"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
}
}
Dit is een geweldig voorbeeld van wat je NIET moet doen. Multi-geneste structuren zoals die hierboven kunnen erg problematisch zijn en kunnen een enorme achteruitgang van prestaties veroorzaken.
De manier waarop Firebase toegang krijgt tot een knooppunt is door alle gegevens van de kinderen te downloaden en vervolgens over alle knooppunten van hetzelfde niveau (alle kinderen van de ouders) te itereren. Stel je nu een database voor met verschillende gebruikers , die elk honderden (of zelfs duizenden) berichten hebben . Toegang tot een post kan in dit geval mogelijk honderden megabytes aan ongebruikte gegevens laden. In een meer gecompliceerde toepassing kan het nesten dieper zijn dan slechts 4 lagen, wat zou resulteren in nutteloze downloads en iteraties.
De goede weg
Het afvlakken van dezelfde structuur zou er zo uitzien
{
// "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
}
}
Dit spaart een enorme hoeveelheid overhead door over minder knooppunten te itereren om toegang te krijgen tot een doelobject. Alle gebruikers die geen berichten hebben, zouden niet bestaan in de berichtenbranche en daarom is het helemaal nutteloos om die gebruikers op de verkeerde manier te herhalen.
Tweerichtingsrelaties
Het volgende is een voorbeeld van een eenvoudige en minimale universiteitsdatabase die tweerichtingsrelaties gebruikt
{
"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
}
}
Merk op dat elke student een lijst met cursussen heeft en elke cursus een lijst met ingeschreven studenten .
Redundantie is niet altijd een slechte aanpak. Het is waar dat het opslagruimte kost en te maken heeft met het bijwerken van meerdere vermeldingen bij het verwijderen of bewerken van een gedupliceerd knooppunt; in sommige scenario's waarin gegevens niet vaak worden bijgewerkt, kan het ophalen / schrijven echter aanzienlijk worden vergemakkelijkt door tweerichtingsrelaties.
In de meeste scenario's waar een SQL-achtige query nodig lijkt, is het inverteren van de gegevens en het creëren van tweerichtingsrelaties meestal de oplossing.
Overweeg een toepassing met behulp van de bovenstaande database die de mogelijkheid vereist om:
- Maak een lijst van de vakken die een bepaalde student volgt en ...
- Maak een lijst van alle studenten in een bepaalde cursus
Als de databasestructuur eenrichtingsverkeer was geweest, zou het ongelooflijk langzamer scannen of zoeken op een van de twee bovenstaande vereisten. In sommige scenario's maakt redundantie frequente bewerkingen sneller en veel efficiënter, waardoor de kosten op de lange termijn te verwaarlozen zijn.