Mer om spørringer og organisering av data i Cloud Firestore
Fra datamodellering med relasjonsdatabaser (SQL) er du kanskje vant til at data organiseres over flere tabeller som har relasjoner til hverandre. Om vi for eksempel har en database over hoteller og vil registrere hotellrommene på hvert enkelt hotell, ville vi i SQL ha lagd en tabell for hoteller og en tabell for hotellrom. Så hadde vi koblet disse sammen med en en-til-mange-relasjon.
I dokumentbaserte databaser (NoSQL) organiseres data på en annen måte. Siden hvert enkelt databaseobjekt er lagret som et frittstående dokument, med i utgangspunktet ingen regler for hvilke data som skal inn i hvert enkelt dokument, kan vi ikke basere oss på koblinger med nøkler og fremmednøkler, slik som i SQL. I dokumentbaserte databaser er dokumenter i stedet organisert i samlinger (collections) og undersamlinger (subcollections). Hotelldatabasen i eksempelet vårt vil da være organisert med alle hotellene i ei samling, og rommene vil være undersamlinger til hvert hotell.
Dette kan virke ulogisk om du er vant til relasjonsdatabaser, der det legges mye vekt på struktur, og der det er et viktig prinsipp å unngå dobbeltlagring, men begge modellene følger det samme prinsippet: Ett hotell har flere rom, og ett rom hører til ett hotell.
NoSQL gir deg derimot mer fleksibilitet. Det er ingenting i veien for at flere hoteller har like romnummer, som de ofte har, fordi rommene lagres under hvert hotell, og ID-ene trenger da bare å være unike for hvert hotell. Det er heller ikke noe problem om et hotell ikke har romnummer, men unike navn på rommene, eller kombinasjoner av bokstaver og tall. Det kan også variere hva slags informasjon som er relevant å ha med i databasen ut fra profilen til hotellet. Noen hoteller har kanskje fokus på velvære og vil registrere om rommet har boblebad, steamdusj eller massasjestoler, mens andre vil bare registrere om rommet har bad eller ikke. Det er ikke noe problem i en NoSQL-database.
Hva med mange-til-mange-relasjoner? Se for deg en database for å registrere elever, hvilke fag de har tatt, og hvilken karakter de har fått i de ulike fagene. En datamodell for denne relasjonsdatabasen kan se slik ut:
I Firebase kan dette gjøres på nesten samme måte ved å lage to parallelle samlinger for elever og fag og ei egen samling for å holde orden på hvilke elever som har tatt hvilke fag, og hvilke karakterer de har fått.
Forskjellen på dette og en mange-til-mange-relasjon i SQL er hvordan spørringer fungerer. I SQL kunne vi ha brukt ei spørring med JOIN for å hente data fra flere tabeller samtidig. NoSQL har ikke støtte for fremmednøkler og JOIN-operasjoner, så for å hente ut data fra flere tabeller, må vi kjøre flere separate spørringer. I NoSQL kan vi heller ikke definere på forhånd hvilke felt vi vil hente ut, slik som vi kan gjøre i SQL med SELECT.
For å hente ut navn og karakter på alle elever i faget Utvikling kunne SQL-spørringa ha sett slik ut:
I Cloud Firestore må vi lage flere atskilte spørringer, slik:
Hvis du har brukt SQL før, vet du at du i SQL kan kombinere betingelser, sorterting, gruppering og mer for å få akkurat det resultatet du ønsker fra databasen. På grunn av måten data er organisert i Cloud Firestore på, er det en del begrensninger på hvordan du kan utforme spørringer. Hvis du har en betingelse (where()
), kan du ikke sortere (orderBy()
) etter noe annet enn den parameteren du brukte i betingelsen.
I dette eksempelet vil du få ei feilmelding fordi det er brukt ulike parametere i where()
(alder) og orderBy()
(etternavn). Dette er fordi ei slik spørring vil ta lengre tid å gjennomføre, og det vil skape mer trafikk til og fra databasen. Det er likevel mulig å gjennomføre ei slik spørring ved å lage en sammensatt indeks (composite index) i Firebase-konsollen. Dette er det mulig å gjøre direkte fra feilmeldinga du får hvis du prøver å kjøre spørringa i eksempelet. Feilmeldinga vil inneholde en lenke til Firebase-konsollen som lar deg opprette akkurat den sammensatte indeksen du trenger, men du bør være forsiktig med å lage for mange, da du bare har mulighet til å lage 50 sammensatte indekser til hver database. Det er mer hensiktsmessig å sortere resultatet du får tilbake (som en array) enn at Firestore sorterer dette for deg.
På samme måte vil du i utgangspunktet ikke kunne kjøre spørringer mot flere undersamlinger samtidig. I hotelleksempelet over vil du for eksempel ikke kunne søke etter ledige dobbeltrom fra flere hoteller samtidig. Dette kan også løses ved å lage en sammensatt indeks i Firebase-konsollen, eller du kan kjøre flere separate spørringer mot hvert hotell og samle resultatene i ei liste (array), som du kan sortere og søke i via ditt eget skript.
Mer informasjon
Firebase tilbyr informasjon om hvordan Firestore-databasen er bygd opp, og hvordan den brukes i videospillelista "Get to know Cloud Firestore" på YouTube.
Her er lenke til to videoer som forklarer prinsippene bak det du har lest om i denne artikkelen:
Guoskevaš sisdoallu
Ved hjelp av datamodellering planlegger man hvordan en database skal bygges opp, ved å sette opp tabeller og angi hvilke forhold disse har til hverandre.
Når vi skal hente data fra Cloud Firestore, kan vi hente ut ett enkelt dokument, alle dokumentene i ei samling, eller vi kan hente data med spørringer.