Van datasilo naar database door hardware
Wanneer “meer data” ineens chaos wordt
Je team groeit van een paar losse exports naar een serieuze datastroom: logs, click-events, transactiegegevens, productdata. In het begin werkt een simpele aanpak—iedere afdeling heeft z’n eigen mapje met bestanden—maar ineens lopen jobs vast, klopt “de waarheid” niet meer, en duurt een lookup of restore veel te lang. Je merkt dat het probleem niet alleen de hoeveelheid data is, maar vooral hoe opslag en toegang georganiseerd zijn.
Dit is precies het kantelpunt waarop organisaties historisch van datasilo’s (losse, afdeling-gebonden bestanden) naar database-achtige systemen bewogen. Niet omdat databases “magisch” zijn, maar omdat hardware en opslagtechniek bepaalde patronen goedkoop maakten (sequentieel scannen), en andere patronen juist extreem duur (veel willekeurige updates of lookups zonder index).
In deze les kijk je naar die verschuiving door één lens: hardware als dwingende vormgever. Je leert welke hardware-eigenschappen ervoor zorgden dat we nieuwe software-abstracties nodig kregen, en hoe dat direct aansluit op je dagelijkse data engineering-keuzes: wanneer kun je file-gebaseerd blijven, en wanneer wil je database-structuren.
De basis: datasilo, database en wat hardware eigenlijk “afdwingt”
Een paar definities om de rest scherp te houden:
-
Datasilo: data zit opgesloten in losse bestanden of systemen per team/applicatie, met eigen definities en weinig gedeelde governance. Integratie gebeurt via exports, handmatige merges, of ad-hoc scripts.
-
Database (in brede zin): een systeem dat niet alleen bytes opslaat, maar ook structuren en garanties biedt: records/rijen, indexen, integriteit, gelijktijdigheid, en vaak transacties of consistente snapshots.
-
Access pattern: hoe je data benadert—sequentieel (scan/stream) versus random (veel kleine punt-reads of punt-writes). Dit bepaalt of throughput of latency de bottleneck wordt.
-
Fysieke I/O-eenheid: opslag leest en schrijft in blokken/sectoren. Je vraagt misschien “één record”, maar de hardware verplaatst en levert blokken.
-
Latency vs throughput: latency is de vaste kost per I/O (positioneren, metadata, wachten); throughput is de snelheid als je eenmaal doorstroomt (grote scans).
De kernprincipes sluiten aan op het idee uit eerder materiaal: ponskaarten en tape dwongen je tot batch, sort–merge–write, terwijl disks random access mogelijk maakten maar met mechanische latency. Bestanden blijven sterk in sequentiële patronen, maar zodra je veel gelijktijdigheid, punt-updates, of consistente reads tijdens writes wilt, schuif je richting database-abstracties.
Een nuttige analogie: een datasilo is een gebouw met losse archiefruimtes per afdeling. Iedereen kan dozen (bestanden) opslaan, maar niemand beheert centraal welke doos de waarheid bevat of hoe je snel een specifieke pagina vindt. Een database is eerder een archief met catalogus, indices en regels: je kunt gericht zoeken, je kunt vastleggen wie wat wanneer wijzigde, en je kunt voorkomen dat twee mensen hetzelfde document tegelijk “half” aanpassen.
Hardware als oorzaak: waarom files niet meer genoeg waren
1) Van sequentiële bulk naar gemengde workloads
Toen opslag vooral sequentieel was (tape-denken), was de dominante strategie: lees alles, verwerk in batches, schrijf een nieuw bestand. Dat werkte goed omdat één lange streaming run de enorme throughput van sequentiële I/O uitbuitte. Zelfs als je “iets kleins” wilde veranderen, was de goedkoopste methode vaak: reconstructie via rebuild of een master + transaction log-achtige aanpak (basisbestand plus delta’s).
Maar zodra organisaties meer interactieve vragen kregen—rapportages on demand, operationele dashboards, “zoek mij klant X nu”—kregen ze een gemengde workload. Sequentiële scans bleven belangrijk, maar daarnaast ontstonden duizenden kleine reads en updates. Hardware maakt dan meteen duidelijk waar de breuklijn zit: veel kleine random I/O’s worden latency-dominant. Een bestand dat bij scans snel is, kan bij punt-lookups ineens instorten omdat je telkens een nieuwe blokread en metadata-pad aflegt.
Een typische misvatting is: “We hebben toch snelle storage, dus random reads zijn prima.” In praktijk betaal je niet alleen de media-latency, maar ook de stapeling van overhead: open/close, metadata, cache misses, en slechte locality als data fysiek verspreid ligt. Daarom ontstond de behoefte aan een laag die expliciet records en locaties beheert: niet “zoek maar in bytes”, maar “hier is de rij, hier is de index, hier is de pagina”.
Best practice die hieruit volgt is hardware-nuchter: ontwerp je opslag volgens je access pattern. Als je vooral batch doet, maximaliseer sequentiële throughput met immutable snapshots en duidelijke run-grenzen. Als je veel punt-toegang nodig hebt, investeer je in structuren die random access economisch maken: indexen, clustering, page layouts en gecontroleerde updates.
2) Blokken, pages en waarom “één record updaten” duur is
Opslag werkt in blokken; databases vertalen dat naar pages (pagina’s) waarin meerdere records staan. Dit lijkt een detail, maar het is precies de brug van hardware naar database-ontwerp. In een file-wereld denk je snel in “regels” (CSV) of “objecten” (JSON), maar de hardware leest een blok, en het OS cachet blokken. Als records variabele lengte hebben, dan is “in-place update” niet alleen logisch lastig, maar ook fysiek: een groeiend record kan niet meer “passen” op dezelfde plek, waardoor je moet verplaatsen, herschrijven of fragmenteren.
Daarom zie je historisch en praktisch zoveel nadruk op:
-
Fixed vs variable-length records: fixed-length maakt offsets voorspelbaar; variable-length vraagt om extra indirection (pointers) en ruimtebeheer.
-
Clustering: records die vaak samen opgevraagd worden, wil je op dezelfde page/blok om random I/O te verminderen.
-
Write-amplification: een kleine wijziging kan leiden tot het herschrijven van veel meer data (bij files vaak het hele bestand, bij databases vaak een page plus log).
Een veelvoorkomende fout in data engineering is het “database-gedrag” op files plakken: één groot bestand en daar “even” rijen aanpassen. In werkelijkheid creëer je óf een append-only delta (die je later moet consolideren), óf een dure rewrite. Best practice is: kies expliciet. Of je gaat voor immutable + consolidatie (file-vriendelijk), of je gebruikt een systeem dat updates beheerst met pages, free space management en logging (database-vriendelijk).
Om het verschil scherp te zien helpt een vergelijking:
| Dimensie | Datasilo / files als datalaag | Database-achtige opslag |
|---|---|---|
| Fysieke eenheid | Werkt met bestanden; hardware/OS werkt met blokken en caching zonder kennis van records. Daardoor is “één record” altijd indirect. | Werkt met pages die bewust records groeperen; de storage-engine beheert layout, free space en record-locaties. |
| Updates | Punt-updates zijn conceptueel lastig; vaak eindig je met rebuild of append-delta’s en later merge/compaction. | Punt-updates zijn een first-class operatie binnen pages; wijzigingen worden meestal beschermd met logging en herstelmechanismen. |
| Toegangsperformance | Scans en bulk writes zijn sterk; veel kleine random reads/writes worden snel latency-dominant en onvoorspelbaar. | Indexen en clustering maken punt-toegang goedkoper; nog steeds bestaan latency-kosten, maar je beperkt het aantal fysieke touches. |
| Zichtbaarheid van “half werk” | Zonder extra afspraken kan een consumer een bestand lezen terwijl het nog geschreven wordt; “compleet” is een applicatievraag. | Consistente reads/snapshots en gecontroleerde commits maken het makkelijker om “af” versus “half” te onderscheiden. |
3) Concurrency: wanneer meerdere processen de boel breken
In een datasilo-omgeving is single-writer vaak impliciet: één batchproces schrijft één output. Zodra je meerdere writers krijgt—meerdere services, meerdere pipelines, meerdere teams—wordt gelijktijdigheid een hardware- én softwareprobleem. Op file-niveau heb je permissies en locks, maar die zijn meestal grof: óf je blokkeert te veel (slechte throughput), óf je blokkeert te weinig (race conditions, corrupte outputs, “last write wins”).
Hardware versterkt dit: random I/O en metadata-updates onder concurrency zorgen voor onvoorspelbaarheid. Als honderden kleine files worden aangemaakt (small files-probleem), wordt niet alleen de data-I/O maar ook de metadata-laag een bottleneck. Je ziet dan symptomen die lijken op “compute tekort”, maar de echte bottleneck is: te veel kleine operaties met hoge latency en coördinatiekosten.
Dat verklaart waarom databases zulke nadruk leggen op concurrency control: niet als luxe, maar als noodzaak zodra je meerdere gelijktijdige gebruikers van dezelfde waarheid hebt. Denk aan het verschil tussen “we plaatsen elke nacht een nieuwe snapshot” (weinig concurrency-eisen) en “tien services updaten klantstatussen door de dag heen” (hoge concurrency-eisen). In het tweede geval wil je een systeem dat voorkomt dat lezers halve updates zien en dat writers elkaar niet kapot schrijven.
Best practice voor file-gebaseerde pipelines blijft: ontwerp voor fase-scheiding (producer schrijft, consumer leest pas na completion marker) en vermijd multi-writer op dezelfde artefacten. De pitfall is denken dat die afspraken vanzelf blijven gelden als de organisatie groeit. De typische overgang naar database-achtige opslag gebeurt precies wanneer die afspraken niet meer schaalbaar zijn in mensen en processen.
[[flowchart-placeholder]]
Twee uitgewerkte voorbeelden uit data engineering
Voorbeeld 1: Van “afdelingsexports” naar één betrouwbare klantdimensie
Stel: Sales heeft een CSV met klantsegmenten, Support heeft een export met tickets, Finance heeft een dump met facturen. In het begin integreren jullie dit door ’s nachts alles in een lake-directory te droppen en met scripts te joinen. De workload is vooral sequentieel: grote scans, sort/merge, en “schrijf een nieuwe output”. Dat past perfect bij file-sterktes: throughput, eenvoud, en herstel via reruns.
Dan verandert de vraag: het bedrijf wil één “customer 360” tabel die elke ochtend klopt en door meerdere teams tegelijk gebruikt wordt. Plots zijn er nieuwe eisen: dezelfde klant-id moet overal consistent zijn, late-arriving correcties moeten worden verwerkt, en niemand mag halffabricaten zien. Als je dit met alleen files blijft doen, moet je extra afspraken stapelen: immutable outputs per run, atomische rename of success markers, manifesten, en een vast consolidatieritme voor delta’s. Dat werkt, maar het is vooral proces- en discipline-gedreven.
De hardware-kant wijst je ondertussen op de pijn: zodra gebruikers “even” een specifieke klant willen opvragen (punt-lookups) of zodra meerdere pipelines tegelijk dezelfde dimensie willen updaten, wordt file-toegang onhandig. Je gaat óf steeds scannen (duur), óf allerlei partities en kleine bestanden maken (metadata overhead), óf je introduceert een index-achtige structuur—en daarmee bouw je feitelijk database-concepten na. Het voordeel van database-achtige opslag is dan dat die concepten ingebouwd zijn: records, indexen, concurrency control en consistente zichtbaarheid. De beperking blijft: je ruilt eenvoud in voor complexere operatie en beheerkosten, maar je krijgt voorspelbaarheid terug.
Voorbeeld 2: Nachtelijke batch 3× trager door “per event een lookup”
Een pipeline verwerkt miljoenen events en doet voor elk event een lookup in een referentiebestand: “zoek productinfo bij product-id”. Op papier is dat klein werk—één record per event—maar fysiek is het een worst-case patroon. Je dwingt het systeem tot heel veel kleine, verspreide reads: elke lookup betaalt latency (positioneren, blok lezen, cache miss), en de totale runtime explodeert. Als het referentiebestand ook nog eens fysiek gefragmenteerd raakt, wordt het onvoorspelbaar: dezelfde code, andere dag, andere performance.
Een hardware-vriendelijke herontwerpstap is terug naar sequentiële kracht: maak van de join een streaming-probleem. Je sorteert (of groepeert) events op de join-sleutel en zorgt dat de referentie ook gesorteerd of geclusterd is. Daarna voer je een merge-join-achtig proces uit: twee gesorteerde stromen in één pass combineren en een nieuw snapshot schrijven. Je verschuift de kosten van “miljoenen random reads” naar “een paar grote scans en een sort”, wat op storage bijna altijd stabieler is. Je pipeline wordt bovendien herstelvriendelijk: als een run faalt, schrijf je simpelweg opnieuw naar een tijdelijke locatie en publiceer je pas als alles compleet is.
De beperking van deze aanpak is eerlijk: dit is batch-denken. Als de business nu realtime per request productinfo wil vastleggen of wijzigen, dan komt dezelfde spanning terug. Files kunnen dat, maar alleen met extra lagen (delta logs, compaction, manifests) en strakke coördinatie. Een database-achtige storage-engine is juist gebouwd om die mix van reads/writes en gelijktijdigheid te dragen vanuit de fysieke realiteit van pages, logging en indexen.
Een bruikbare afsluiter: kies op basis van access pattern, niet op modewoorden
De rode draad is eenvoudig: hardware maakt sommige patronen goedkoop en andere duur. Datasilo’s en file-opslag werken uitstekend zolang je vooral sequentieel verwerkt, outputs immutable houdt, en “compleetheid” expliciet markeert. Zodra je organisatie vraagt om veel punt-toegang, gelijktijdige updates, en één gedeelde waarheid, ontstaat druk richting database-abstracties: indexen, pages, concurrency control en consistente zichtbaarheid.
Een praktisch mentaal model om mee te nemen:
-
Als je ontwerp lijkt op sort → merge → write en je kunt leven met periodieke consolidatie, dan passen files bij je hardware-realiteit.
-
Als je ontwerp lijkt op “duizenden kleine reads/writes per seconde” of “veel writers, één waarheid”, dan heb je database-achtige structuren nodig—of je gaat ze onbedoeld zelf bouwen.
Waar je staat na dit deel
-
Je herkent hoe sequentieel vs random access rechtstreeks uit hardware komt en je ontwerp dwingt tot batch/streaming of index-gedreven toegang.
-
Je kunt uitleggen waarom blokken/pages en recordlayout bepalen of punt-updates en lookups goedkoop of duur zijn.
-
Je ziet concurrency niet als “feature”, maar als het moment waarop datasilo-afspraken breken en databases hun waarde bewijzen.
Met deze hardware-bril kun je in echte pipelines sneller diagnosticeren of een probleem “meer compute” vraagt, of vooral een betere match tussen workload en opslagmodel. Dat maakt je ontwerpen stabieler, voorspelbaarder en beter schaalbaar—precies wat je in data engineering nodig hebt.