Hendelsestabeller med kun tillegg
Registrer det som skjedde, og overskriv aldri.
Hendelsestabeller med kun tillegg er en gratis leksjon i SQL Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i SQL Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i SQL Academy inneholder totalt 4 leksjoner.
Hva er en append-only-tabell?
En append-only-hendelsestabell er en tabell der rader bare settes inn – de oppdateres eller slettes aldri. Hver rad representerer noe som skjedde på et bestemt tidspunkt.
Dette mønsteret er grunnlaget for event sourcing. I stedet for å lagre den gjeldende tilstanden lagrer du hver endring som en uforanderlig hendelse, slik at du får en fullstendig historikk som kan revideres.
Opprette en hendelsestabell
En godt utformet hendelsestabell registrerer hvem som gjorde hva, på hvilken ressurs og når. Kolonnen occurred_at registrerer det nøyaktige tidsstempelet, og DEFAULT NOW() sørger for at den alltid fylles ut automatisk.
Legg merke til at det ikke finnes noen UPDATE eller DELETE i dette designet – radene er permanente når de først er skrevet.
CREATE TABLE account_events (
id BIGSERIAL PRIMARY KEY,
account_id BIGINT NOT NULL,
event_type TEXT NOT NULL,
payload JSONB,
occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Sette inn hendelser
Hver handling en bruker utfører – innlogging, innskudd av penger eller endring av en e-postadresse – blir en ny rad. Du går aldri tilbake og redigerer en tidligere hendelse. Hvis noe må korrigeres, setter du i stedet inn en kompenserende hendelse.
På denne måten bevares hele hendelsesforløpet i riktig rekkefølge.
INSERT INTO account_events (account_id, event_type, payload)
VALUES
(42, 'account_opened', '{"plan": "free"}'),
(42, 'email_verified', '{"email": "alice@example.com"}'),
(42, 'plan_upgraded', '{"from": "free", "to": "pro"}');Lese hele historikken
Fordi hver tilstandsendring lagres som en rad, er det enkelt å hente hele historikken for en konto med en SELECT-spørring sortert etter tid. Du kan spille av hele livsløpet til en post, fra den første hendelsen til den nyeste.
SELECT
id,
event_type,
payload,
occurred_at
FROM account_events
WHERE account_id = 42
ORDER BY occurred_at ASC;Utlede gjeldende tilstand
Med en append-only-tabell lagrer du ikke den gjeldende tilstanden direkte – du utleder den ved å lese den nyeste relevante hendelsen. Her er den gjeldende planen for konto 42 det som den nyeste plan_upgraded- eller account_opened-hendelsen angir.
Ved å bruke ORDER BY occurred_at DESC LIMIT 1 henter du effektivt det nyeste øyeblikksbildet.
SELECT payload->>'to' AS current_plan
FROM account_events
WHERE account_id = 42
AND event_type IN ('account_opened', 'plan_upgraded')
ORDER BY occurred_at DESC
LIMIT 1;Håndheve uforanderlighet med regler
Append-only-garantien kan håndheves på databasenivå ved hjelp av en RULE som stille ignorerer alle UPDATE- eller DELETE-operasjoner på tabellen. Dette hindrer utilsiktede endringer fra alle applikasjoner som har skrivetilgang.
En trigger som utløser et unntak, er et enda strengere alternativ, siden den aktivt avviser operasjonen med en feil.
CREATE RULE no_update_events AS
ON UPDATE TO account_events
DO INSTEAD NOTHING;
CREATE RULE no_delete_events AS
ON DELETE TO account_events
DO INSTEAD NOTHING;Uforanderlighet via trigger
En trigger som utløser et unntak, er strengere enn en stille regel – applikasjonen mottar en feil umiddelbart hvis den forsøker å endre en tidligere hendelse. Dermed blir feil synlige i stedet for å bli ignorert i stillhet.
CREATE OR REPLACE FUNCTION deny_event_mutation()
RETURNS TRIGGER AS $$
BEGIN
RAISE EXCEPTION 'Event table is append-only: % is not allowed', TG_OP;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_deny_event_mutation
BEFORE UPDATE OR DELETE ON account_events
FOR EACH ROW EXECUTE FUNCTION deny_event_mutation();Telle hendelser over tid
Append-only-tabeller gjør tidsbaserte analyser enkle. Siden hver hendelse har et tidsstempel, kan du gruppere etter dag, uke eller måned uten ekstra kolonner. Eksempelet nedenfor teller hvor mange hendelser av hver type som inntraff per dag.
SELECT
DATE_TRUNC('day', occurred_at) AS day,
event_type,
COUNT(*) AS total
FROM account_events
GROUP BY 1, 2
ORDER BY 1, 2;Gjenopprette tilstand på et bestemt tidspunkt
En av de mest nyttige egenskapene ved en hendelseslogg er muligheten til å gjenopprette tilstanden til en post slik den var på et tidligere tidspunkt. Du trenger bare å filtrere hendelser frem til ønsket tidsstempel – ingen utvidelse for tidsreiser er nødvendig.
Dette er svært verdifullt ved feilsøking, revisjon og overholdelse av forskriftskrav.
-- What plan was account 42 on at the end of last month?
SELECT payload->>'to' AS plan_at_snapshot
FROM account_events
WHERE account_id = 42
AND event_type IN ('account_opened', 'plan_upgraded')
AND occurred_at <= DATE_TRUNC('month', NOW()) - INTERVAL '1 second'
ORDER BY occurred_at DESC
LIMIT 1;Kompenserende hendelser i stedet for korrigeringer
Når en feil oppdages – for eksempel en feilaktig belastning – skal du ikke slette den feilaktige hendelsen. I stedet setter du inn en kompenserende hendelse som annullerer eller reverserer den. Begge hendelsene forblir synlige i loggen og viser nøyaktig hva som skjedde, og når korrigeringen ble gjort.
Dette holder revisjonssporet komplett og gjør det mulig å oppdage manipulering.
-- A charge was applied by mistake; record a reversal
INSERT INTO account_events (account_id, event_type, payload)
VALUES (
42,
'charge_reversed',
'{"reason": "billing_error", "reverses_event_id": 17}'
);Partisjonere store hendelsestabeller
Hendelsestabeller vokser raskt. Partisjonering etter et tidsintervall holder de enkelte partisjonene små, gjør intervallspørringer raskere og gjør det mulig å arkivere eller slette gamle partisjoner uten å berøre nyere data.
PostgreSQLs deklarative partisjonering gjør dette enkelt: definer en RANGE-partisjon på occurred_at, så lar du databasen rute innsettinger automatisk.
CREATE TABLE account_events_2025
PARTITION OF account_events
FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');
CREATE TABLE account_events_2026
PARTITION OF account_events
FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');Kunnskapstest: append-only-tabeller
Test forståelsen din av utforming av append-only-hendelsestabeller.
Oppsummering: Append-only-hendelsestabeller
I denne leksjonen lærte du å utforme og bruke append-only-hendelsestabeller:
- Uforanderlighet – rader settes inn én gang og endres aldri. Tidligere hendelser er fakta.
- Fullstendig historikk – hver tilstandsendring bevares, noe som muliggjør fullstendige revisjonsspor og point-in-time-spørringer.
- Kompenserende hendelser – feil korrigeres ved å legge til en ny reverserende hendelse, ikke ved å slette den gamle.
- Håndheving – regler eller triggere på databasenivå hindrer utilsiktede endringer.
- Skalerbarhet – intervallpartisjonering holder store hendelseslogger effektive over tid.
Append-only-tabeller er bærebjelken i event sourcing, CQRS-arkitekturer og alle systemer der muligheten til å revidere og historisk nøyaktighet er avgjørende.
Lær deg SQL med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 46
- Leksjoner
- 183
Ofte stilte spørsmål
Er leksjonen «Hendelsestabeller med kun tillegg» gratis?
Ja – hele teksten i «Hendelsestabeller med kun tillegg» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av SQL Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i SQL Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Hendelsestabeller med kun tillegg»?
Registrer det som skjedde, og overskriv aldri. Du øver på SQL Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med SQL Academy?
Ingen tidligere erfaring er nødvendig. SQL Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Hendelsestabeller med kun tillegg»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne SQL Academy-leksjonen?
Ja. Alle SQL Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Hvorfor ta vare på historikken
- Hendelsestabeller med kun tillegg
- Temporale og versjonerte rader
- Gjenoppbygge tilstand fra hendelser