Databaser og dataservices — sammenspillet mellem frontend og data
Tabeller, nøgler, SQL og hvordan en webløsning taler sikkert med sine data
En webside, der ikke husker noget, er ikke meget værd i praksis — en webshop skal huske ordrer, et forum skal huske indlæg, og et login skal huske, hvem du er. Det er databasens opgave. Bekendtgørelsen for webudvikleruddannelsen peger direkte på dette som et selvstændigt fagområde: eleven skal kunne redegøre for sammenspillet mellem databasestruktur og frontend og anvende relevante dataservices til udvikling af webløsninger.
§Relationsdatabasen — tabeller, rækker og nøgler
Den mest udbredte type database på webbet er relationsdatabasen. Data ligger i tabeller, hvor hver række er én post, og hver kolonne er et bestemt felt — en tabel med brugere har fx kolonner for navn, e-mail og oprettelsesdato. Hver række har en primærnøgle, et unikt id, der peger præcist på netop den post. Sammenhænge mellem tabeller laves med fremmednøgler: en ordre-tabel gemmer ikke kundens navn og adresse igen, men blot kundens id, som peger tilbage til kunde-tabellen. Det er selve grundtanken i det relationelle — data er delt op, men bundet sammen via nøgler.
§SQL og CRUD — de fire grundhandlinger
SQL (Structured Query Language) er sproget, man bruger til at spørge en relationsdatabase. Uanset hvilket program eller framework der ligger imellem, ender det næsten altid ud i de samme fire grundlæggende handlinger, ofte kaldet CRUD.
- 01Create — opret en ny post (SQL: INSERT)
- 02Read — hent en eller flere poster (SQL: SELECT)
- 03Update — ret i en eksisterende post (SQL: UPDATE)
- 04Delete — fjern en post (SQL: DELETE)
§Normalisering — undgå at gemme det samme flere steder
Normalisering er arbejdet med at strukturere tabellerne, så samme oplysning ikke gemmes flere steder unødigt. Gemmer man en kundes adresse på hver eneste ordre, skal alle ordrer rettes, hvis kunden flytter — og gør man det ikke konsekvent, opstår modstridende data. Ved i stedet at gemme adressen ét sted og lade ordrerne pege dertil via en fremmednøgle, findes sandheden kun ét sted. Det koster lidt mere at hente data samlet (man skal 'joine' tabellerne), men vinder markant i konsistens og vedligeholdelse.
§Relationel eller NoSQL — vælg efter data, ikke efter mode
Ikke al data passer lige godt til faste tabeller med kolonner. NoSQL-databaser (dokument-, nøgle/værdi- og grafdatabaser er de mest almindelige typer) gemmer data mere fleksibelt, ofte som dokumenter uden en fast skabelon for hvert felt. De egner sig godt til data, der varierer meget i form, eller hvor man skal skalere til meget store mængder skrivninger. Relationsdatabaser vinder til gengæld, når data har klare sammenhænge, og man har brug for garantier for, at en handling enten gennemføres helt eller slet ikke (transaktioner).
| Egenskab | Relationsdatabase | NoSQL (fx dokumentdatabase) |
|---|---|---|
| Struktur | Faste tabeller med kolonner | Fleksible dokumenter, varierende felter |
| Sammenhænge | Fremmednøgler og joins | Ofte data samlet i ét dokument |
| Bedst til | Data med klare relationer og krav om konsistens | Data der varierer i form, eller meget høj skrivehastighed |
| Sprog | SQL | Varierer fra system til system |
§ORM'en — broen mellem kode og database
I stedet for at skrive rå SQL-forespørgsler overalt i backend-koden bruger mange en ORM (Object-Relational Mapper). Den lader dig arbejde med databasens tabeller som almindelige objekter i dit programmeringssprog og oversætter det til SQL bag kulissen. Det gør koden lettere at læse og mindre fejlbehæftet — men det er stadig vigtigt at forstå, hvad ORM'en reelt sender til databasen, ikke mindst når en forespørgsel bliver langsom, fordi den henter langt mere data, end siden reelt skal bruge.
§Dataservicen skal sikres, ikke kun bygges
En dataservice er det lag, der stiller data til rådighed for frontend — typisk et API, der taler HTTP, som beskrevet i artiklen om web-API'er. Adgangen til data skal kontrolleres på samme måde som resten af backend: kun autentificerede og autoriserede kald må læse eller ændre data, forbindelsen til databasen skal beskyttes med et login, der aldrig ligger i frontend-koden, og følsomme data bør kun sendes videre, når det reelt er nødvendigt for opgaven.
“En database er ikke bare et sted, data ligger og venter — det er en struktur, der enten hjælper dig eller forhindrer dig i at stole på dine egne data.”
— Almindelig læreregel i databasedesign