Fangst av dataendringer

Innen databaser er **fangst av dataendringer** flere designmønstre for å bestemme om data har blitt endret og sporing av disse slik at man kan foreta en handling ved hjelp av de endrede dataene. Man ender dermed opp med en endringshistorikk eller **deltadrevet [[datamengde]]**.

Datafangst av endringer oppstår ofte i datavarehusmiljøer ettersom fangst og bevaring av datatilstander over tid er en av de viktigste funksjonene til et datavarehus, men oppfanging av dataendringer kan også brukes i enhver database eller andre datasamlinger.

Generelt kan man si at fangst av dataendringer er en tilnærming til dataintegrasjon som baserer seg på identifisering, oppfanging og leveranse av endringer gjort på datakildene til en organisasjon.

## Metoder
Systemutviklere kan sette opp mekanismer for å fange opp dataendringer på en rekke måter, og på et hvilket som helst systemnivå eller kombinasjoner av systemnivåer fra applikasjonsnivå ned til fysisk lagring.

Et forenklet scenario kan være at en datasystem har data som man mistenker har endret seg fra et tidligere tidspunkt, og at et annet datasystem som må foreta en handling basert på disse dataendringene. Førstnevnte system er da kildesystemet, mens sistnevnte er målsystemet. Det er mulig at kilden og målet er samme fysiske system, men dette vil ikke endre det logiske designmønsteret. Flere løsninger for oppfanging av dataendringer kan eksistere innenfor samme system.

### Tidsstempler på rader
Tabeller hvis endringer må fanges opp kan ha en kolonne som representerer tidspunktet fro siste endring, og LAST_UPDATE er et eksempel på et vanlig kolonnenavn. Hvilken som helst rad i hvilken som helst tabell som har et nyere tidsstempel i denne kolonnen enn forrige datafangst kan da anses å være endret.

Tidsstempler på rader er også ofte brukt for optimistisk låsing, hvilket medfører at denne kolonnen ofte er tilgjengelig.

### Versjonstall på rader
Databasedesignere gir tabeller hvis endringer må fanges med en kolonne som inneholder et versjonsnummer, og VERSION_NUMBER er et eksempel på et vanlig kolonnenavn.

Én teknikk er å markere hver endrede rad med et versjonsnummer. Det blir da vedlikeholdt en nåværende versjon for tabellen, eller i noen tilfeller nåværende *grupper* av tabeller. Dette lagres i en støttestruktur som for eksempel en referansetabell. Når en oppfanging oppstår anses alle data med siste versjonsnummer å være endrede. Når fangsten er fullført vil referansetabellen oppdateres med et nytt versjonsnummer.

Denne teknikken må ikke forveksles med versjonering på radnivå brukt for optimistisk låsing. Med optimistisk låsing gis hver rad et uavhengig versjonsnummer, typisk etter en sekvensiell teller. Dette muliggjør at prosessen kan oppdatere en rad atomisk og inkrementere telleren hvis og bare hvis en annen prosess ikke har inkrementert telleren. Imidlertid kan ikke fangstmekanismen bruke versjonering på radnivå for å finne alle endringer, med mindre man kjenner startversjonen for hver rad, og dette er følgelig upraktisk å vedlikeholde.

### Statusindikatorer på rader
Denne teknikken kan enten supplere eller komplementere tidsstempler og versjonskontroll. En mulighet er at statusindikatoren i form av en boolsk verdi kan brukes for å indikere at en tabellrad har endret seg. Ellers kan statusindikatoren fungere som et komplement til de forrige metodene ved å indikere at en rad, til tross for å ha et nytt versjonsnummer eller en senere dato, fortsatt ikke bør oppdateres på målsystemet (for eksempel dersom dataene trenger menneskelig validering).

### Tid, versjon og status på rader
Denne tilnærmingen kombinerer de tre tidligere diskuterte metodene. Som nevnt, er det ikke uvanlig å se flere løsninger for fangst av dataendringer innenfor et enkelt system, men kombinasjonen av tid, versjon og status gir en spesielt kraftig mekanisme og programmerere bør utnytte dem som en trio der det er mulig. De tre elementene er ikke redundante eller overflødige. Ved å bruke dem sammen får man mulighet for logikk som for eksempel, "fang opp alle data for versjon 2.1 som ble endret mellom 2005-06-01 kl. 12:00, og 2005-07-01 kl. 12:00 hvor statuskoden angir at raden er klar for produksjon."

### Utløsere på tabeller
Utløsere på tabeller kan inkludere et publish/subscribe-mønster for å kommunisere de endrede dataene til flere mål. Ved denne tilnærmingen vil utløseren sørge for at hendelser (*events*) i transaksjonstabeller blir logget i en annen køtabell som senre kan bli gjennomgått. Eksempelvis kan transaksjoner mot en tabell kalt Accounts utløse at det i en separat køtabell blir ført historikk over dette, eller til og med deltaene (endringene). Køtabellen kan eksempelvis ha et skjema med følgende felter: *Id*, *TableName*, *RowId*, *TimeStamp* og *Operation*. Dataene som settes inn for Account sample kan være følgende: *1*, *Accounts*, *76*, *2008-11-02 kl. 00:15*, *Update*. Mer kompliserte design kan kanskje også logge de faktiske dataene som ble endret. En slik køtabell kan deretter bli gjennomgått for å replikere dataene fra kildesystemet til målet.

Et eksempel på denne teknikken er et mønster kalt loggutløser (*log trigger*).

### Hendelsesdrevet programmering
Hendelsesdrevet programmering går ut på at man koder endringer på passende steder i applikasjonen for å gi et intelligent og skarpsindig signal om at dataene har endret seg. Ulempen med dette er at det krever programmering programmering istedenfor bruk av utløsere (som kan være enklere å implementere). Fordelen er at man kan få en mer presis og ettertraktet oppfanging av dataendringer etter hva målsystemet er ute etter. Dette kan for eksempel være etter en COMMIT eller kun etter at visse kolonner har endret seg til visse verdier.

### Loggskannere
De fleste databasehåndteringssystemer har en transaksjonslogg som registrerer endringer som har blitt gjort på databaseinnhold og metadata. Ved å skanne og tolke innholdet i transaksjonsloggen til databasen kan man fange opp de endringer som er gjort i databasen på en ikke-inngripende måte.

En utfordring med å bruke transaksjonslogger for fangst av dataendringer er at det ikke finnes noen standard på struktur, innhold og bruk av transaksjonslogger og at disse følgelig pleier å være spesifikke for de enkelte databasehåndteringssystemene. De fleste databasehåndteringssystemer dokumenterer heller ikke det interne formatet på transaksjonsloggene deres, men det er noen som publiserer programmeringsgrensesnitt for transaksjonslogger (for eksempel Oracle, DB2, SQL/MP, SQL/MX og SQL Server 2008).

Andre utfordringer med bruk av transaksjonslogger for fangst av dataendringer inkluderer:

* Koordinere lesing av transaksjonslogger og arkivering av loggfiler (databasehåndteringssystemer arkiverer vanligvis loggfiler offline på jevnlig basis).
* Oversettelse mellom fysiske lagringsformater som registreres i transaksjonslogger og de logiske formatene forventes vanligvis av brukere av databasen (for eksempel lagrer noen transaksjonslogger minimale bufferforskjeller som ikke er direkte nyttige for å endringsforbrukere).
* Håndtering av endringer i formater i transaksjonslogger mellom ulike versjoner av databasehåndteringssystemet
* Eliminere ukommiterte endringer som databasen skrev til transaksjonsloggen og senere rullet tilbake
* Håndtere endringer i metadata til tabellene i databasen

Løsninger for fangst av dataendringer basert på transaksjons-loggfiler har også klare fordeler som inkluderer:

* Minimal innvirkning på databasen (særlig dersom man bruker loggshipping for å prosessere loggene med en dedikert vert)
* Ingen behov for programmatiske endringer i applikasjoner som bruker databasen
* Lav latens for å hente endringer
* Transaksjonell integritet. Loggskanning kan produsere en endringsstrøm som replikerer de originale transaksjonene i den rekkefølgen de ble begått. En slik endringsstrøm inkluderer endringer gjort på alle tabeller som deltar den fangede dataendringen.
* Ingen grunn til å endre databaseskjemaet

## Konfunderende faktorer
Som i andre komplekse domener kan den endelige løsningen for fangst av dataendringer måtte komme til å balansere flere motstridende hensyn.

### Uegnede kildesystemer
Datafangst av endringer både øker kompleksiteten og reduserer verdien dersom kildesystemet lagrer endringer i metadata når dataene i seg selv ikke har blitt endret. For eksempel sporer noen datamodell hvilken bruker som sist så på men ikke endret data i samme struktur som dataene. Dette resulterer i støy i systemet for fangst av dataendringer.

### Sporing av endringer
Å faktisk spore endringer avhenger av datakilden. Dersom dataene blir holdt i en moderne database vil fangst av dataendringer være en enkel sak hvor man bare trenger de rette tilgangene. To teknikker som er i vanlig bruk er:

* Sporing av endringer ved hjelp av databaseutløsere
* Lesing av transaksjonsloggen imens den blir skrevet eller kort tid etterpå

Dersom dataene ikke befinner seg i en moderne database vil fangsten av dataendringer være en programmeringsutfordring.

### ''Push'' kontra ''pull''
* ***Push'' ("dytte")''': Kildeprosessen lager et "stillbilde" (''snapshot'') av endringene i sin egen prosess og leverer rader nedstrøms. Prosessen nedstrøms bruker så dette bildet, skaper sin egen delmengde og leverer de til påfølgende prosesser.
* ***Pull* ("trekke")*': Målsystemet som er umiddelbart nedstrøms fra kilden sender en forespørsel om å få data fra kilden. Målet nedstrøms leverer så et bilde til neste mål på lik linje med push-modellen.

### Alternativer

Noen ganger brukes endringstrege dimensjoner (SCD) som en alternativ metode. CDC og SDC er like ved at begge metodene kan oppdage endringer i et datasett. De vanligste formene for SCD er type 1 (overskriv), type 2 (behold historikk) eller 3 (kun forrige og nåværende verdi). SCD 2 kan være nyttig dersom historikk er nødvendig i målsystemet. CDC overskriver i målsystemet (i likhet med SCD1), og er ideelt når bare de endrede dataene trenger å komme frem til målsystemet, altså *deltadrevne [[datasett]]*.

## Se også
* Datalasting
* Referanseintegritet, en situasjon hvor alle datareferanser er gyldige
* Endringstreg dimensjon (SCD), en datadimensjon som inneholder relativt statiske data som kan endre seg sakte, men uforutsigbart, istedenfor etter faste intervaller

## Referanser