Oppfanging av dataendringer

Innen databaser er oppfanging av dataendringer (engelsk: change data capture, CDC) 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.
Oppfanging av dataendringer oppstår ofte i datavarehusmiljøer ettersom oppfanging og bevaring av datatilstander over tid er en av de viktigste funksjonene til et datavarehus, men oppfanging av dataendringer kan brukes i enhver database eller andre datasamlinger.
Generelt kan man si at oppfanging 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 oppfanging av 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å oppfanges 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 sist dataoppfanging kan da ansees å 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å oppfanges 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 ansees alle data med siste versjonsnummer å være endrede. Når oppfangingen 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 oppfangingsmekanismen 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 oppfanging 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 å replisere 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 oppfanging 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 oppfanging 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 databasenLøsninger for oppfanging 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 repliserer de originale transaksjonene i den rekkefølgen de ble begått. En slik endringsstrøm inkluderer endringer gjort på alle tabeller som deltar den oppfangede dataendringen.
Ingen grunn til å endre databaseskjemaet


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


=== Uegnede kildesystemer ===
Oppfanging av dataendringer 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 oppfanging av dataendringer .


=== Sporing av oppfangingen ===
Å faktisk spore endringer avhenger av datakilden. Dersom dataene blir holdt i en moderne database vil oppfanging 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 oppfanging 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 som en metode.


== Se også ==
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 ==