Hvorfor ta vare på historikken
Revisjon, angre og analyse av fortiden.
Hvorfor ta vare på historikken er en gratis leksjon i SQL Academy på CoddyKit. Dette er leksjon 1 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.
Problemet med å overskrive data
Hver gang du kjører UPDATE eller DELETE, forsvinner de gamle dataene for godt. Det høres effektivt ut, men skaper reelle problemer: Du kan ikke svare på spørsmål som hva var prisen forrige tirsdag? eller hvem endret denne posten, og når?
Å ta vare på historikken betyr å lagre hver versjon av en rad, ikke bare den nyeste. I denne leksjonen utforsker du hvorfor dette er viktig, og hvordan SQL hjelper deg med å gjøre det.
Tre grunner til å ta vare på historikken
Det finnes tre klassiske grunner til å bevare historiske data i en database:
1. Revisjon – dokumenter at en endring fant sted, hvem som gjorde den, og når.
2. Angring – rull tilbake en feil uten å gjenopprette hele databasen.
3. Analyse – svar på spørsmål om fortiden, oppdag trender og sammenlign perioder.
En godt utformet strategi for historikk dekker alle tre behovene uten å bruke unødvendig mye lagringsplass på duplikater.
En enkel revisjonstabell
Den enkleste fremgangsmåten er en separat revisjonstabell som registrerer hver endring. Hver rad inneholder den gamle verdien, den nye verdien, hvem som gjorde endringen, og når.
Nedenfor ser du en revisjonstabell for tabellen products. Kolonnen operation lagrer INSERT, UPDATE eller DELETE.
CREATE TABLE products_audit (
audit_id SERIAL PRIMARY KEY,
product_id INT NOT NULL,
operation VARCHAR(6) NOT NULL, -- INSERT / UPDATE / DELETE
old_price NUMERIC(10,2),
new_price NUMERIC(10,2),
changed_by TEXT NOT NULL,
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Fylle ut revisjonstabellen
Du kan skrive til en revisjonstabell manuelt, men den mest pålitelige fremgangsmåten er en databasetrigger som utløses automatisk hver gang data endres. På denne måten kan ingen applikasjonskode omgå loggen.
Her setter vi inn én revisjonsrad direkte for å illustrere strukturen før vi går gjennom triggere.
INSERT INTO products_audit (product_id, operation, old_price, new_price, changed_by)
VALUES (42, 'UPDATE', 9.99, 12.49, 'alice');
SELECT * FROM products_audit ORDER BY changed_at DESC LIMIT 5;Lese revisjonssporet
Når det har samlet seg rader i revisjonstabellen, kan du spørre i den for å besvare spørsmål om revisjon. Spørringen nedenfor viser hele prishistorikken for ett produkt, med den nyeste først.
SELECT
changed_at,
changed_by,
operation,
old_price,
new_price
FROM products_audit
WHERE product_id = 42
ORDER BY changed_at DESC;Gyldighetsdatoer: historikk basert på gyldighetstid
En revisjonstabell registrerer når du gjorde endringen (transaksjonstid). Noen ganger må du også spore når noe faktisk var sant i virkeligheten – dette kalles gyldighetstid.
Ved å legge til kolonnene valid_from og valid_to i hovedtabellen oppretter du historikk basert på gyldighetstid, også kalt en dimensjon som endres sakte (SCD Type 2).
CREATE TABLE employee_history (
id SERIAL PRIMARY KEY,
employee_id INT NOT NULL,
department TEXT NOT NULL,
salary NUMERIC(10,2) NOT NULL,
valid_from DATE NOT NULL,
valid_to DATE -- NULL means current record
);
-- Current record for employee 7
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Engineering', 85000, '2023-01-01');Oppdatere en post som endres sakte
Når en ansatt bytter avdeling, oppdaterer du ikke raden med UPDATE. I stedet avslutter du den gamle raden ved å angi valid_to og setter inn en ny rad uten sluttdato. På denne måten bevarer du hele historikken.
-- Step 1: close the current record
UPDATE employee_history
SET valid_to = '2024-06-01'
WHERE employee_id = 7 AND valid_to IS NULL;
-- Step 2: insert the new record
INSERT INTO employee_history (employee_id, department, salary, valid_from)
VALUES (7, 'Product', 90000, '2024-06-01');
-- Verify history
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
ORDER BY valid_from;Spørre på et bestemt tidspunkt
Med kolonner for gyldighetstid kan du spørre hva som var sant på en bestemt dato – noe som ikke ville vært mulig med en vanlig UPDATE-modell.
WHERE-klausulen kontrollerer at måldatoen faller innenfor radens gyldighetsintervall.
-- What department and salary did employee 7 have on 2023-09-15?
SELECT department, salary, valid_from, valid_to
FROM employee_history
WHERE employee_id = 7
AND valid_from <= '2023-09-15'
AND (valid_to > '2023-09-15' OR valid_to IS NULL);Systemversjonerte temporale tabeller
Moderne SQL-databaser (PostgreSQL 16+, SQL Server, MySQL 8) støtter systemversjonerte temporale tabeller. Databasen sporer automatisk transaksjonstid i skjulte kolonner, og du kan spørre etter tidligere tilstander med en spesiell syntaks.
Eksempel fra SQL Server – konseptet er det samme på tvers av databasemotorer:
-- SQL Server / MariaDB style (illustrative)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
status VARCHAR(20),
total NUMERIC(10,2),
SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);
-- Query historical state
SELECT * FROM orders FOR SYSTEM_TIME AS OF '2024-01-15 12:00:00'
WHERE order_id = 100;Bruke historikk til å angre
Historikktabeller er ikke bare til lesing – de kan brukes til å angre feil. Hvis en batchjobb ødela 500 prisoppføringer, kan du gjenopprette dem fra audit-tabellen uten å røre en sikkerhetskopi.
-- Undo all price changes made by the bad batch job at a specific time
UPDATE products p
SET price = a.old_price
FROM products_audit a
WHERE p.id = a.product_id
AND a.operation = 'UPDATE'
AND a.changed_by = 'batch_job'
AND a.changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';
-- Confirm affected rows
SELECT COUNT(*) AS rows_restored FROM products_audit
WHERE changed_by = 'batch_job'
AND changed_at BETWEEN '2024-03-10 02:00:00' AND '2024-03-10 02:05:00';Analyse over tid
Historikkdata åpner for tidsserieanalyser. Du kan følge med på hvordan et mål utvikler seg, sammenligne tall fra måned til måned eller oppdage avvik – alt uten å berøre et separat datavarehus.
Denne spørringen viser gjennomsnittsprisen for et produkt i hver kalendermåned ved hjelp av audit-tabellen.
SELECT
DATE_TRUNC('month', changed_at) AS month,
ROUND(AVG(new_price), 2) AS avg_price
FROM products_audit
WHERE product_id = 42
AND operation IN ('INSERT', 'UPDATE')
GROUP BY 1
ORDER BY 1;Kunnskapstest
Test forståelsen din av lagring av historiske data i SQL.
Oppsummering: Hvorfor bevare historikk
I denne leksjonen lærte du hvorfor det er risikabelt å overskrive data, og hvordan SQL-mønstre bevarer historikk for revisjon, angreoperasjoner og analyse.
Viktigste punkter:
- Audit-tabeller loggfører alle INSERT-, UPDATE- og DELETE-operasjoner, med hvem som utførte dem og når.
- Rader med valid time (SCD Type 2) bruker kolonnene
valid_from/valid_totil å registrere tidsforløp i den virkelige verden. - Point-in-time-spørringer besvarer historiske spørsmål ved å filtrere på disse datokolonnene.
- Systemversjonerte temporale tabeller automatiserer sporing av transaction time på databasenivå.
- Historikkdata muliggjør målrettede angreoperasjoner og avanserte tidsserieanalyser uten behov for sikkerhetskopier.
Å bevare fortiden er ikke unødvendig overhead – det er grunnlaget for pålitelige systemer som kan revideres.
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 «Hvorfor ta vare på historikken» gratis?
Ja – hele teksten i «Hvorfor ta vare på historikken» 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 «Hvorfor ta vare på historikken»?
Revisjon, angre og analyse av fortiden. 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 1 av 4.
Hvor lang tid tar leksjonen «Hvorfor ta vare på historikken»?
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