Databases zonder mysterie

Het schema van «Kotomarket»

11 min
What you'll learn
  • de juiste tabel vinden binnen de vijf tabellen van «Kotomarket»: users, products, orders, order_items, events
  • een ER-diagram lezen: de kardinaliteit van een verbinding bepalen (1:N, N:M, 1:1) aan de hand van waar de vreemde sleutel ligt
  • een «veel-op-veel»-verbinding modelleren via een tussentabel met twee FK's — zoals order_items met order_id + product_id
  • uitleggen waarom je de inhoud van een bestelling niet als een string met id's direct in orders kunt opslaan

Vandaag brengt QUERY de hele inventaris in één keer naar de hoofdtafel. Vijf gloeiende panelen hangen in de lucht en draaien langzaam rond: een kaart van de wereld die is overgebleven. Ernaast flikkert het conserveringslogboek dat bij de momentopname hoort, met één onderstreepte regel: «Ik draag vijf tabellen over en het spoor van een zesde. — K.» Je telt de panelen. Precies vijf. Waar is het spoor?

QUERY: Laat je niet afleiden door sporen. Leer eerst deze vijf zo goed kennen dat je met je ogen dicht de weg vindt. De rest laat het archief zelf zien zodra je er klaar voor bent.

De vijf tabellen van «Kotomarket»

Verderop werken we met deze database: een momentopname van een webwinkel uit 2024. Gebruik die als plattegrond van de winkel: wie er binnenkwam, wat er in de etalage lag, wat mensen kochten en welke handelingen ze vóór de aankoop verrichtten.

TabelWat erin staat
userskopers: id, naam, stad en registratiedatum
productsproducten in de etalage: id, naam, categorie, prijs en voorraad
ordersbestellingen: id, user_id, datum, status en bedrag
order_itemsde inhoud van bestellingen: welk product, hoeveel stuks en tegen welke prijs
eventsgedragsgebeurtenissen: weergaven, toevoegingen aan het winkelmandje en aankopen

De verbindingen lees je zo: één user → veel orders; één order → veel order_items; één product → veel order_items. Raak je verdwaald, open dan het schema aan de rechterkant: dat is de plattegrond van de winkelvloer.

Laten we in de tabel met bestellingen kijken: elke rij heeft een user_id, een verwijzing naar de koper. Zo wordt de ene tabel met de andere verbonden en verandert de kaart van vijf losse eilanden in één geheel.

Vijf holografische tabelpanelen draaien als een sterrenbeeld, verbonden door draden; aan de zijkant is vaag de gestippelde omtrek van een zesde paneel te zien
De kaart van het archief: vijf tabellen en hun verbindingen. Het conserveringslogboek belooft ook «het spoor van een zesde», maar dat is voorlopig nergens te vinden.

Kotomarket’s five tables

From here on we’ll be working with this database — a of an online shop from 2024. Hold it like a map of the store: who walked in, what’s on the shelves, what they bought, and what they did before buying.

TableWhat it holds
usersbuyers: id, name, city, and signup date
productsstorefront items: id, name, category, price, and stock
ordersorders: id, user_id, date, status, and total
order_itemsorder contents: which product, how many, and at what price
eventsbehavioral events: views, add-to-carts, and purchases

The links read like this: one user → many orders; one order → many order_items; one product → many order_items. If you get lost, open the schema on the right — it’s like the floor plan of the shop.

Let’s peek into the orders table: every row has a user_id — a reference to a buyer. That’s how one table links to another, and the map stops being five separate islands.

Bestellingen en hun verbinding met de koper via user_id:
Query result
iduser_idstatustotal_amount
118paid5980.00
210paid19750.00
326cancelled9560.00
426paid15530.00
58paid26710.00
637paid42110.00

Hoe je een ER-diagram leest

De kaart die QUERY ontvouwde, heet in de praktijk een ER-diagram (entity–relationship): rechthoeken zijn tabellen, de lijnen ertussen zijn verbindingen via vreemde sleutels. Het belangrijkste op zo'n lijn is de kardinaliteit: hoeveel rijen aan de ene kant horen bij hoeveel rijen aan de andere kant.

  • 1:N, één-op-veel — de meest voorkomende verbinding. Eén koper, veel bestellingen. De vreemde sleutel ligt altijd aan de kant van de «veel»: user_id staat in orders, niet andersom. Dat is de leesregel: vind je de FK, dan heb je de N-kant gevonden.
  • N:M, veel-op-veel — in één bestelling zitten veel producten, en één product kan in veel bestellingen voorkomen. Zo'n verbinding kun je in een relationele database niet rechtstreeks uitdrukken: er is geen plek om één vreemde sleutel neer te leggen. Je modelleert die via een tussentabel — bij ons is dat order_items. Elke rij daarin bevat een paar verwijzingen order_id + product_id en zet één N:M-verbinding om in twee 1:N-verbindingen. Bonus: de verbinding zelf krijgt attributen, zoals het aantal stuks en de prijs op het moment van aankoop.
  • 1:1, één-op-één — komt minder vaak voor. Zo kun je bijvoorbeeld zware of privévelden verplaatsen naar een aparte tabel met dezelfde sleutel.
-- De N:M-ontkoppeling in actie: de paren «bestelling — product» uit order_items
SELECT order_id, product_id, quantity
FROM order_items
LIMIT 6;
usersidnameproductsidpriceordersiduser_ideventsuser_idproduct_idorder_itemsorder_idproduct_iduser_id → idproduct_id → idPKFK (reference)
Het ER-diagram van «Kotomarket»: 1:N-verbindingen van users naar orders en de opsplitsing van N:M tussen orders en products via order_items.

Valkuil: de inhoud van een bestelling direct in orders opslaan, bijvoorbeeld als string '7,12,3' of als array met id's. Zulke data kun je niet met een vreemde sleutel beschermen, niet betrouwbaar tellen en niet zonder omwegen samenvoegen met de etalage. Zie je een «veel-op-veel»-verbinding, maak dan een tussentabel met twee vreemde sleutels, zoals order_items.

Interview question

Sollicitatievraag: hoe realiseer je in een relationele database een «veel-op-veel»-verbinding?

Sterk antwoord: via een tussentabel met twee vreemde sleutels naar de tabellen die je wilt verbinden — zoals order_items met order_id en product_id. Zo zet je N:M om in twee 1:N-verbindingen. In diezelfde tabel kun je meteen attributen van de verbinding bewaren, zoals het aantal en de prijs op het moment van aankoop. De primaire sleutel van zo'n tabel is óf samengesteld uit de twee FK's, óf een surrogaat-id.

Check yourself
Waar in het schema zie je welk product in welke bestelling terechtkwam?