Temporaliteit in projecties
Dit document legt uit hoe temporaliteit werkt in betrouwbare registers. We werken op van de eenvoudigste vorm —alleen de actuele stand— naar unitemporaliteit (geldigheidstijdstippen) en uiteindelijk bitemporaliteit (geldigheids- én registratietijdstippen).
We gebruiken hier een voorbeeld dat zou kunnen bestaan in de basisregistratie personen: We willen de persoonsinformatie opvragen aan de hand van een persoonId (bijvoorbeeld een BSN).
Alleen de actuele stand
De eenvoudigste vorm van een projectie bevat alleen de huidige, actuele stand van zaken. Er wordt geen historische informatie bijgehouden. Deze aanpak is eenvoudig, maar biedt geen mogelijkheden om te beantwoorden hoe de data er in het verleden uitzag.
Output voorbeeld
Een typische query-ingang van een projectie is een REST-api waar je parameters kan opgeven en een output krijgt, in dit voorbeeld in de vorm van json:
GET /persoon?id=41232
{
"persoonId": 41232,
"adres": "Groene woud 3",
"woonplaats": "Gorinchem"
…
}
Het is ten behoeve van performance vaak wenselijk projecties te persisteren, hieronder gerepresenteerd in een tabelvorm.
| id | naam | adres |
|---|---|---|
| 41232 | Piet Pietersen | Groene woud 3 |
Maar in het kader van een betrouwbaar register hebben we nu een probleem als de data wijzigt. Hoe verzorgen we de herhaalbare vraag nadat er op 1 juni 2026 een verhuizing geweest is?
Temporaliteit
Door geldigheidstijdstippen vast te leggen en querybaar te maken kun je veranderingen over tijd volgen. Elke mutatie krijgt een geldigheidstijdstip mee dat aangeeft vanaf wanneer deze in de echte wereld geldt.
Output voorbeeld
Door het geldigheidstijdstip toe te voegen aan de API kunnen we zien dat op 1 juni, voor de verhuizing, het adres Groene woud 3 was, en na de verhuizing Straatweg 4.
Voor verhuizing
GET /persoon?id=41232&geldigheidstijdstip=2026-06-01
{
"persoonId": 41232,
"adres": "Groene woud 3",
"woonplaats": "Gorinchem"
…
}
Na verhuizing
GET /persoon?id=41232&geldigheidstijdstip=2026-06-02
{
"persoonId": 41232,
"adres": "Straatweg 4",
"woonplaats": "Gorinchem"
…
}
In de opslag zien we dat we de uniciteit van een persoonId verliezen: er is een kolom, geldigheid, bij gekomen om de tijdstippen bij te houden. Maar op deze manier kunnen we veranderingen over tijd vastleggen.
| id | geldigheid | naam | adres |
|---|---|---|---|
| 41232 | 1998-06-05 | Piet Pietersen | Groene woud 3 |
| 41232 | 2026-06-02 | Piet Pietersen | Straatweg 4 |
Deze aanpak werkt goed zolang alle mutaties correct zijn, en na elkaar plaatsvinden. Maar wat nu als het Straatweg 42 had moeten zijn in plaats van Straatweg 4?
Correctie: het probleem
Stel, op 2 juni werd het adres geregistreerd als Straatweg 4, maar later bleek dat een typefout. Het had Straatweg 42 moeten zijn. Hoe corrigeer je dit in de projectie?
Als je de fout corrigeert met een mutatie van de bestaande regel ontstaat er een probleem: op 27 juni had de afnemer Straatweg 4 teruggekregen. Die registratie was op dat moment (voor zover bekend) correct, maar wordt achteraf gezien incorrect. De bestaande regel muteren schendt het principe van de herhaalbare vraag: bij dezelfde vraag zou je hetzelfde antwoord terug moeten krijgen. Het (achteraf) aanpassen van een regel in de storage is dus onwenselijk. Maar hoe lossen we dit dan op?
Voor een diepere uitleg over correctie van gevolgen, zie Correctie van gevolgen.
Bitemporaliteit: geldigheid én registratie
De oplossing is bitemporaliteit: naast het tijdstip waarop iets in de echte wereld geldt (geldigheidstijdstip), houden we ook bij wanneer het in ons systeem bekend is geworden: het registratietijdstip.
Output voorbeeld
Voor correctie op 11 juni
GET /persoon?id=41232&
geldigheidstijdstip=2026-06-11&
registratietijdstip=2026-06-28
{
"persoonId": 41232,
"adres": "Straatweg 4",
"woonplaats": "Gorinchem"
…
}
Na correctie op 11 juni
GET /persoon?id=41232&
geldigheidstijdstip=2026-06-11&
registratietijdstip=2026-06-30
{
"persoonId": 41232,
"adres": "Straatweg 42",
"woonplaats": "Gorinchem"
…
}
In onze storage hebben we nog een extra kolom nodig:
| id | geldigheid | registratie | naam | adres |
|---|---|---|---|---|
| 41232 | 1998-06-05 | 2023-02-12 | Piet Pietersen | Groene woud 3 |
| 41232 | 2026-06-02 | 2026-06-02 | Piet Pietersen | Straatweg 4 |
| 41232 | 2026-06-02 | 2026-06-29 | Piet Pietersen | Straatweg 42 |
Deze bitemporele aanpak maakt correctie mogelijk in combinatie met herhaalbaarheid. Je kunt zowel kijken naar hoe het had moeten zijn, als naar wat er op een bepaald moment geregistreerd stond.