Temporales Datenmanagement: IBM DB2 macht‘s möglich

Mit der Datenbank auf Zeitreise
Kommentare

Durch die Zeit reisen – ein Traum so alt wie die Menschheit. Zumindest auf Datenebene kann er nun verwirklicht werden: IBM DB2 für Linux, UNIX und Windows Version 10, seit Ende April 2012 erhältlich, verfügt über eine Zeitmaschine, mit der sich Daten aus der Vergangenheit, Gegenwart und Zukunft betrachten lassen.

Das in DB2 10 integrierte temporale Datenmanagement spart Zeit und Geld. Neue Funktionen zur Auswertung historischer Datensätze und zur Verfolgung zeitlicher Änderungen erleichtern Datenbankadministratoren und Anwendungsentwicklern die Arbeit erheblich. Mit früheren Versionen mussten Trigger oder komplexe Funktionen erzeugt werden, um eine zeitabhängige Betrachtung der Daten zu ermöglichen. Jetzt erleichtert DB2 solche Aufgaben mithilfe temporaler Tabellen sowie durch Abfragen und Semantiken auf der Grundlage von ANSI/ISO SQL:2011.

Anwendungsszenarien einer temporalen Datenhaltung

Temporale Datenhaltung ist in vielen verschiedenen Anwendungsszenarien nützlich:

  1. Für die interne Revision muss ein Kreditinstitut einen Bericht über die in den vergangenen fünf Jahren vorgenommenen Änderungen an den Unterlagen eines Kunden vorlegen.
  2. Im Rahmen eines anhängigen Rechtsstreits muss ein Krankenhaus seinen Kenntnisstand über den medizinischen Zustand eines Patienten vor der Umstellung auf eine neue Behandlung überprüfen.
  3. Ein Kunde legt Widerspruch gegen die Regulierungsentscheidung einer Versicherung im Zusammenhang mit einem Autounfall ein. Die Versicherung muss nun überprüfen, welche Versicherungsbedingungen zum Zeitpunkt des Unfalls Bestand hatten.
  4. Ein Onlinereisebüro möchte, dass das System bestimmte logische Widersprüche bei Reisebuchungen erkennt. Falls also ein Kunde für acht Tage ein Hotel in Rom bucht und für drei dieser Tage einen Mietwagen in New York reserviert, möchte das Reisebüro benachrichtigt werden, um dies prüfen zu können.
  5. Ein Einzelhändler will sicherstellen, dass für jedes Produkt in seinem Sortiment innerhalb eines beliebigen Zeitraums höchstens ein einzelner Rabatt gewährt wird.
  6. Wegen eines Fehlers bei der Dateneingabe im Zusammenhang mit einem dreimonatigen Sonderzinssatz für die Kreditkarte eines Neukunden muss die Bank nun eine Korrektur vornehmen – und einen neuen Saldo berechnen, falls erforderlich.

Bei jedem dieser Szenarien ist Zeit ein kritischer Faktor. Die neuen Funktionen für temporale Datenhaltung in DB2 unterstützen mit relativ geringem Aufwand die Entwicklung zeitbezogener Anwendungen und Abfragen. Vor der Vertiefung dieser neuen Fähigkeiten werden zunächst zeitbezogene Konzepte vorgestellt und dabei auch die Unterschiede zwischen System Time (Bearbeitungszeit) und Business Time (Gültigkeitszeit bzw. Anwendungszeit) erläutert.

Basiskonzepte

System Time ermöglicht das Nachverfolgen von Änderungen in einer Tabelle, etwa wenn eine Versicherungspolice geändert oder ein Kredit vergeben wird (Historisierung). Business Time ermöglicht die zeitlich korrekte Darstellung von Geschäftsvorfällen, beispielsweise die jeweils aktuellen Bedingungen einer Versicherungspolice oder der jeweilige Zinssatz eines Kredits. Bisweilen wird Business Time auch als Gültigkeits- oder Anwendungszeit bezeichnet. Sollen sowohl System Time als auch Business Time dargestellt werden, müssen beide Arten temporaler Daten in einer Tabelle abgebildet sein. Solche Tabellen nennt man dann bitemporal.
Für die Szenarien 1 und 2 werden Informationen über die Bearbeitungszeit benötigt, um den historischen Zustand einer oder mehrerer Tabellen darstellen zu können. Für die Szenarien 3 bis 6 werden Informationen über die Gültigkeitszeit benötigt, um die Gültigkeitszeiträume verschiedener Geschäftsvorfälle darzustellen. Darüber hinaus wird für Szenario 6 möglicherweise auch die Bearbeitungszeit benötigt – das heißt bitemporale-Daten – sofern die Bank den Dateneingabefehler rückwirkend korrigieren und gleichzeitig festhalten möchte, wann der Fehler korrigiert wurde.
Periodenkonzepte sind sowohl für Gültigkeitszeit als auch für Bearbeitungszeit relevant. Eine Periode gibt den Startzeitpunkt und den Endzeitpunkt eines Zeitraumes an. Bei DB2 lassen sich die Start- und Endzeiten einer Periode mit zwei Spalten einer Tabelle festlegen. Die Unterstützung temporaler Daten für neue oder vorhandene Tabellen erfolgt mithilfe von Syntaxerweiterungen der Anweisungen CREATE TABLE und ALTER TABLE.

Beispielszenario

Ein einfaches Beispiel mit Musterdaten zeigt, welche Möglichkeiten die Funktionen zur temporalen Datenhaltung in DB2 bieten. Im folgenden Beispiel geht es um Policen für Kfz-Versicherungen, die der Einfachheit halber in einer einzelnen Tabelle dargestellt sind. Die Tabelle enthält verschiedene Informationen, die in solchen Policen in der Regel erfasst sind: Versicherungsnummer (id), Fahrgestellnummer (vin), voraussichtliche jährliche Kilometerleistung (annual_mileage), Kostenübernahme für Leihwagen bei schadensbedingter Fahrzeugreparatur (rental_car) und die Deckungssumme (coverage_amt) einschließlich Sachschäden, Heilkosten usw. Tabelle 1 zeigt den Aufbau der Tabelle POLICY ohne temporale Unterstützung. Wie können die temporalen Funktionen von DB2 die Verwaltung solcher Versicherungspolicen erleichtern?

POLICY

ID

VIN

annual_mileage

rental_car

coverage_amt

1111

A1111

10000

Y

500000

Tabelle 1: Die Ausgangstabelle POLICY

Datenverwaltung mit System Time

Das Konzept System Time in DB2 bietet die Möglichkeit, die zeitliche Entwicklung von Daten zu verfolgen und darzustellen. Wird eine Tabelle mit einem Bearbeitungszeitintervall (System Time Period) erzeugt, erfasst DB2 sämtliche Änderungen an dieser Tabelle automatisch und speichert „alte“ Sätze in einer separaten History-Tabelle mit identischer Struktur. Werden zeitbezogene Abfragen an die Tabelle gerichtet, greift DB2 bei Bedarf transparent auf die automatisch gepflegte History-Tabelle zu. Diese Funktion ermöglicht den einfachen Umgang mit historischen Daten und macht komplexe Abfragen mit WHERE-Klauseln, diversen Zeitstempeln und JOIN-Bedingungen überflüssig.

Definition einer Tabelle mit System Time

Das Definieren einer Tabelle mit System Time erfolgt in drei einfachen Schritten:
Basistabelle für aktuelle Daten definieren:
Zusätzlich zu den eigentlichen Spalten einer Tabelle werden drei TIMESTAMP (12)-Spalten angelegt, zwei für die Start-/Endzeitpunkte der Bearbeitungszeit und eine für den Zeitpunkt des Transaktionsstarts. DB2 nutzt diese Spalte, um festzustellen, wann die Transaktion erstmals eine Anweisung zur Änderung der Daten in der Tabelle ausführte. Die drei TIMESTAMP-Spalten können mit GENERATED ALWAYS definiert werden, damit DB2 die Werte bei jedem INSERT, UPDATE und DELETE automatisch erzeugt. Damit ist sichergestellt, dass die Werte stets in die Datenbank eingetragen werden und dass die Zeitstempel korrekt sind. Definiert man diese Spalten zusätzlich noch als IMPLICITLY HIDDEN, werden sie bei SELECT *-Anweisungen nicht angezeigt.

  1. History-Tabelle definieren: Erzeugen einer Tabelle mit identischer Struktur, wie sie die Tabelle mit den aktuellen Daten aufweist. Das lässt sich einfach mit der Anweisung CREATE TABLE . . . LIKE bewerkstelligen.
  2. Versionierung für die Basis-Tabelle aktivieren: An einem Beispiel wird deutlich, wie einfach es mit DB2 ist, mit System Time automatisch verschiedene Versionen von Daten zu pflegen.

Erster Schritt: Erzeugen einer Tabelle mit einer SYSTEM_TIME-Periode (Listing 1).

CREATE TABLE policy (
   id             INT primary key not null,
   vin            VARCHAR(10),
   annual_mileage INT,
   rental_car     CHAR(1),
   coverage_amt   INT,
   sys_start      TIMESTAMP(12) GENERATED ALWAYS AS ROW BEGIN NOT NULL,
   sys_end        TIMESTAMP(12) GENERATED ALWAYS AS ROW END NOT NULL,
   trans_start    TIMESTAMP(12) GENERATED ALWAYS AS TRANSACTION START ID
                                IMPLICITLY HIDDEN,
   PERIOD SYSTEM_TIME (sys_start, sys_end)
 ); 

Zweiter Schritt: Erzeugen einer zugehörigen History-Tabelle:

CREATE TABLE policy_history LIKE policy; 

Dritter Schritt: Versionierung aktivieren:

ALTER TABLE policy ADD VERSIONING USE HISTORY TABLE policy_history;

Tabelle 2 und Tabelle 3 zeigen das mit o. g. Anweisungen erzielte Ergebnis.

POLICY

ID

VIN

annual_mileage

rental_car

coverage_amt

sys_start

sys_end

trans_start

 

 

 

 

 

 

 

 

Tabelle 2: Die Tabelle POLICY (mit aktuellen Daten)

POLICY_HISTORY

ID

VIN

annual_mileage

rental_car

coverage_amt

sys_start

sys_end

trans_start

 

 

 

 

 

 

 

 

Tabelle 3: Die Tabelle POLICY_HISTORY (mit historischen Daten)

Vorhandene Tabellen können mit der Anweisung ALTER TABLE für die Verwaltung historischer Daten genutzt werden. Hierzu müssen die oben erwähnten Spalten sys_start und sys_end eingefügt und PERIOD SYSTEM_TIME definiert werden. DB2 unterstützt automatische Schemaänderungen für zugehörige History-Tabellen, sofern für die Basistabellen, wie in Listing 1 bis 3 beschrieben, die Versionierung aktiviert ist. Wird also eine Spalte in die Tabelle POLICY eingefügt, erweitert DB2 die Tabelle POLICY_HISTORY ebenfalls um die gleiche Spalte.

Dateneingabe in eine Tabelle mit System Time

Das Einfügen von Daten in eine Tabelle mit System Time unterscheidet sich nicht von der Dateneingabe in herkömmliche Tabellen. Beispielsweise müssen am 15. November 2010 zwei neue Datensätze für Kfz-Versicherungen in die Tabelle POLICY eingegeben werden. Das geschieht mit folgenden Anweisungen:

INSERT INTO policy(id, vin, annual_mileage, rental_car, coverage_amt)
     VALUES(1111,  'A1111',  10000, 'Y', 500000);

INSERT INTO policy(id, vin, annual_mileage, rental_car, coverage_amt)
     VALUES(1414,  'B7777',  14000, 'N', 750000);

Beim Einfügen der neuen Zeilen in die aktuelle Tabelle erzeugt DB2 die Zeitstempel für die Spalten sys_start und trans_start. Diese Zeitwerte waren in den INSERT-Anweisungen nicht angegeben. DB2 hat sie automatisch eingefügt. Tabelle 4 und Tabelle 5 zeigen, wie die Tabellen POLICY und POLICY_HISTORY nach den Einfügungen aussehen. Zur Vereinfachung zeigen Tabelle 4 und Tabelle 5 nur die Datumswerte der Spalten sys_start und sys_end an. Die Daten werden im Format YYYY-MM-DD angezeigt. Da die Spalte mit der Transaktionsstartzeit als verborgen definiert wurde, wird sie hier bei Tabelle 4 und Tabelle 5 nicht angezeigt.

POLICY

ID

VIN

annual_mileage

rental_car

coverage_amt

sys_start

sys_end

1111

A1111

10000

Y

500000

2010-11-15

9999-12-31

1414

B7777

14000

N

750000

2010-11-15

9999-12-31

Tabelle 4: Inhalt der aktuellen Tabelle nach den INSERTs am 15. November 2010

POLICY_HISTORY

ID

VIN

annual_mileage

rental_car

coverage_amt

sys_start

sys_end

 

 

 

 

 

 

 

Tabelle 5: Inhalt der History-Tabelle nach den INSERTs am 15. November 2010

Die Werte in der Spalte sys_start in der Tabelle POLICY geben an, wann die Sätze eingefügt wurden, im Beispiel am 15. November 2010. Die Werte für sys_end wurden auf den 30. Dezember 9999 gesetzt, um anzuzeigen, dass die Daten dieser Sätze noch aktuell sind.

Aktualisieren von Daten in einer Tabelle mit System Time

Werden Daten in der Tabelle aktualisiert, sichert DB2 automatisch eine Vorversion der Daten in der zugehörigen History-Tabelle. Dieser Vorgang läuft transparent ab und erfordert weder Programmierung noch Benutzereingriff. Angenommen, die folgende Anweisung wird am 31. Januar 2011 ausgeführt, um die Deckungssumme für Police 1111 in 750000 zu ändern:

UPDATE policy
  SET coverage_amt = 750000
  WHERE id = 1111;

DB2 aktualisiert den Wert in der Zeile der aktuellen Tabelle. Dann verschiebt DB2 eine Kopie des alten Satzes in die History-Tabelle. In beiden Tabellen speichert DB2 darüber hinaus die Start- und Endzeiten für die Werte in diesen Zeilen. So wird der Wert für diese Zeile in der Spalte sys_end in der History-Tabelle auf den Transaktionszeitpunkt der UPDATE-Anweisung gesetzt. All dies geschieht automatisch und transparent für den Anwender. DB2 speichert auch die Transaktionsstartzeit in den Tabellen 6 und 7 [1], auch wenn das hier nicht angezeigt wird. Alle weiteren Aktualisierungen werden natürlich auf ähnliche Weise abgewickelt.

Löschen von Daten aus einer Tabelle mit System Time

Bei einem Löschvorgang entfernt DB2 die jeweiligen Daten aus der aktuellen Tabelle und überträgt eine Kopie der gelöschten Daten in die zugehörige History-Tabelle. DB2 setzt den Endzeitpunkt der gelöschten Daten in der History-Tabelle auf den Transaktionsstartpunkt der DELETE-Anweisung. Dieser Vorgang läuft transparent ab und erfordert weder Programmierung noch Benutzereingriff. Angenommen, die Zeile mit den Daten für Police 1414 wird am 31. März 2012 durch folgende Anweisung gelöscht:

DELETE FROM policy WHERE id = 1414;

DB2 löscht den Satz in der Tabelle POLICY und fügt diesen in die History-Tabelle ein. Die Spalte sys_end wird automatisch auf das aktuelle Datum, also auf den Wert 31. März 2012 gesetzt.

Abfragen an eine Tabelle mit System Time

Abfragen an eine Tabelle mit System Time lassen sich einfach formulieren. Syntax und Semantik herkömmlicher SELECT-Anweisungen bleiben unverändert. So gelten SELECT-Anweisungen ohne Zeitraumangaben stets für aktuelle Daten in der Basistabelle. Vorhandene Anwendungen, Prozeduren und Datenbankberichte können also auch nach einer Erweiterung alter Tabellen durch das temporale Konzept weiter genutzt werden. In die SELECT-Anweisung lassen sich nun zusätzlich für den transparenten Zugriff auf historische Daten (oder eine Kombination aus aktuellen und historischen Daten) drei neue Zeitraumangaben aufnehmen. Einige Beispiele zeigen, wie einfach sich zeitbezogene Abfragen formulieren lassen. Die Informationen über Kfz-Versicherungen in der aktuellen und der History-Tabelle entsprechen denen in Tabelle 8 und Tabelle 9. Nun wird folgende Abfrage gestellt:

SELECT coverage_amt 
  FROM policy 
  WHERE id = 1111;

Wie zu erwarten, gibt DB2 einen Satz mit einer Deckungssumme von 250000 zurück. Für Abfragen nach älteren Daten muss eine von drei unterstützten Zeitraumangaben in die FROM-Klausel aufgenommen werden:

  • FOR SYSTEM_TIME AS OF … gibt Daten ab einem bestimmten Zeitpunkt zurück (Listing 2).
  • FOR SYSTEM_TIME FROM … TO … gibt Daten für einen bestimmten Zeitraum zurück. DB2 nutzt hier ein Inclusive-exclusive-Konzept für diese Zeitraumangabe. Das bedeutet: Der angegebene Startzeitpunkt liegt innerhalb des Zeitraums, der Endzeitpunkt nicht (Listing 3).
  • FOR SYSTEM_TIME BETWEEN … AND … gibt Daten zurück, die zwischen bestimmten Start- und Endzeiten liegen. DB2 nutzt hier ein Inclusive-inclusive-Konzept für diese Zeitraumangabe. Das bedeutet: Der angegebene Startzeitpunkt und der Endzeitpunkt liegen innerhalb des Zeitraums
SELECT coverage_amt
  FROM policy FOR SYSTEM_TIME AS OF '2010-12-01'
  WHERE id = 1111;
SELECT count(*)
  FROM policy FOR SYSTEM_TIME FROM '2011-11-30'
                                TO '9999-12-30'
  WHERE vin = 'A1111';

Datenverwaltung mit Business Time

Mit Business Time lässt sich nachverfolgen, wann bestimmte Geschäftsvorfälle gültig waren, gültig sind oder gültig sein werden. Beispiel: Ein Produkt kostet normalerweise 45 Euro, jedoch während eines Aktionszeitraums von einem Monat nur 39 Euro. Für die einfache Darstellung von Gültigkeitszeiten ist das Konzept Business Time vorgesehen. Wie bei der Bearbeitungszeit ist auch für die Gültigkeitszeit (Business Time) die Angabe einer Periode erforderlich (die Start- und Endzeiten der Gültigkeit). Anders als das Konzept System Time wird für Business Time keine separate History-Tabelle benötigt. Frühere, aktuelle und künftige Gültigkeitszeiten und die zugehörigen Geschäftsdaten werden alle in einer einzigen Tabelle verwaltet. Darüber hinaus ist es der Benutzer, der die Start-/Endwerte für die Business-Time-Spalten bei der Dateneingabe festlegt. Weiterhin wird auch für die Transaktionsstartzeit keine Spalte benötigt.

Erzeugen einer Tabelle mit Business Time

Um eine Tabelle mit Business Time zu erzeugen, sind Spalten für die Start-/Endzeitpunkte des Gültigkeitszeitraums sowie eine PERIOD BUSINESS_TIME-Klausel erforderlich. Die Spalten für die Start-/Endzeitpunkte des Gültigkeitszeitraums können vom Typ DATE oder TIMESTAMP sein.
Im folgenden Beispiel wird eine Tabelle für Kfz-Versicherungspolicen erzeugt, in der auch die Gültigkeitszeiten der jeweiligen Daten hinterlegt sind. Im vorliegenden Beispiel sind die Spalten bus_start und bus_end vom Typ DATE. Mit der Klausel PERIOD BUSINESS_TIME wird DB2 angewiesen, diese Spalten zur Nachverfolgung der Start- und Endzeiten für die Gültigkeit von Geschäftsvorfällen in jedem Satz zu nutzen. Um die temporale Integrität der Daten zu gewährleisten, legt DB2 automatisch eine Bedingung (Constraint) fest, die dafür sorgt, dass die Werte in bus_start vor denen in bus_end liegen (Listing 4).

CREATE TABLE policy (
  id              INT NOT NULL,
  vin             VARCHAR(10),
  annual_mileage  INT,
  rental_car      CHAR(1),
  coverage_amt    INT,
  bus_start       DATE NOT NULL,
  bus_end         DATE NOT NULL,
  PERIOD BUSINESS_TIME(bus_start, bus_end),
  PRIMARY KEY(id, BUSINESS_TIME WITHOUT OVERLAPS) );

Die in der CREATE TABLE-Anweisung definierte Bedingung für den Primärschlüssel nutzt die optionale Angabe BUSINESS_TIME WITHOUT OVERLAPS. Damit wird DB2 angewiesen, nur eindeutige Primärschlüsselwerte für jeden Zeitpunkt in Gültigkeitszeiträumen anzulegen. Im vorliegenden Beispiel sorgt BUSINESS_TIME WITHOUT OVERLAPS also dafür, dass keine zwei Versionen oder Zustände derselben Police gleichzeitig bestehen können. Mit der Anweisung ALTER TABLE lassen sich vorhandene Tabellen für die Darstellung von Gültigkeitszeiten nutzbar machen. Hierzu müssen die oben erwähnten DATE- oder TIMESTAMP-Spalten eingefügt und PERIOD BUSINESS_TIME definiert werden.

Einfügen von Daten in eine Tabelle mit Business Time

Das Einfügen einer Zeile in eine Tabelle mit Business Time ist einfach: Es müssen lediglich gültige Werte für alle Spalten mit der Bedingung NOT NULL angegeben werden – auch für die Start- und Endzeitpunkte des Gültigkeitszeitraums. Mit den in Listing 5 zu sehenden Anweisungen lassen sich einige Zeilen in der Tabelle POLICY mit Business Time einfügen.

INSERT INTO policy
  VALUES(1111,'A1111',10000,'Y',500000,'2010-01-01','2011-01-01');
INSERT INTO policy
  VALUES(1111,'A1111',10000,'Y',750000,'2011-01-01','9999-12-30');
INSERT INTO policy
  VALUES(1414,'B7777',14000,'N',750000,'2008-05-01','2010-03-01');
INSERT INTO policy
  VALUES(1414,'B7777',12000,'N',600000,'2010-03-01','2011-01-01');

Wie wird die für diese Tabelle (mit der Klausel BUSINESS_TIME WITHOUT OVERLAPS) vorgeschriebene zeitliche Eindeutigkeit in der Praxis gewährleistet? Dazu wird folgende INSERT-Anweisung eingegeben:

INSERT INTO policy
  VALUES(1111,'A1111',10000,'Y',900000,'2010-06-01','2011-09-01');

DB2 wird diese Anweisung nicht ausführen und eine Fehlermeldung ausgeben. Denn es wurde versucht, eine Zeile für Police 1111 einzufügen, die für einen Zeitraum gilt, für den bereits eine oder mehrere andere Zeilen für diese Police als gültig definiert sind. Es liegt also eine Verletzung der zeitlichen Eindeutigkeit vor. Soll die Deckungssumme für Police 1111 vom 1. Juni 2010 bis 1. September 2011 angepasst werden, ist dafür eine UPDATE-Anweisung erforderlich.

Aktualisieren von Daten in eine Tabelle mit Business Time

Auch Tabellen, die Gültigkeitszeiträume vorsehen, können mit herkömmlichen UPDATE-Anweisungen aktualisiert werden. Zusätzlich verfügbar ist die neue Klausel FOR PORTION OF BUSINESS_TIME zur Beschränkung der Aktualisierung auf einen bestimmten Gültigkeitszeitraum. Sind von der Aktualisierung auch Sätze betroffen, die nicht vollständig innerhalb des angegebenen Zeitraums liegen, aktualisiert DB2 die innerhalb der Zeitraumbedingung liegenden Daten und fügt zusätzliche Sätze ein – zur Protokollierung der alten Werte für Sätze, die nicht innerhalb des angegebenen Zeitraums liegen. An einem Beispiel wird dieser Vorgang verdeutlicht. Die Deckungssumme für Police 1111 soll für den Zeitraum vom 1. Juni 2010 bis 1. September 2011 geändert werden. Die entsprechende UPDATE-Anweisung könnte so aussehen:

UPDATE policy
  FOR PORTION OF BUSINESS_TIME FROM '2010-06-01' TO '2011-09-01'
  SET coverage_amt = 900000
  WHERE id = 1111;

Hierbei ist zu beachten, dass die zeitliche Bedingung für die Abfrage (FOR PORTION OF BUSINESS_TIME FROM … TO …) hinter dem Tabellennamen steht und nicht Teil der WHERE-Klausel ist. Wie in Abbildung 1 gezeigt, gab es ursprünglich zwei Zeilen für Police 1111. Beide sind von der UPDATE-Anweisung betroffen, da der zu aktualisierende Gültigkeitszeitraum teilweise innerhalb der in beiden Zeilen gespeicherten Zeiträume liegt. Diese Überlappung ist im oberen Teil von Abbildung 1 dargestellt. Wenn DB2 die Aktualisierung vornimmt, wird jede der ursprünglichen Zeilen in zwei Zeilen geteilt, wie im unteren Teil dargestellt. DB2 passt die Gültigkeitszeiten der Sätze automatisch an.

 

Abb. 1: Datensatzteilungen durch UPDATE-Anweisung

Löschen von Daten aus einer Tabelle mit Business Time

Das Löschen von Daten aus Tabellen mit Gültigkeitszeiträumen kann mit der Klausel FOR PORTION OF BUSINESS_TIME auf spezifische Zeiträume beschränkt werden. Enthält eine zum Löschen vorgesehene Zeile Daten, die nicht vollständig innerhalb des angegebenen Zeitraums liegen, sorgt DB2 dafür, dass diese Daten erhalten bleiben.

DELETE FROM policy
  FOR PORTION OF BUSINESS_TIME FROM '2010-06-01' TO '2011-01-01'
  WHERE id = 1414;

Tabelle 12 [1] zeigt das Ergebnis nach dem Löschen der Daten in Listing 5 an. Beachten Sie den letzten Satz (id = 1414), bei dem DB2 die Business Time korrigiert hat.

Abfragen an eine Tabelle mit Business Time

Für zeitbezogene Abfragen zur Ermittlung vergangener, aktueller und künftiger Geschäftsvorfälle stehen drei optionale Klauseln zur Verfügung. Natürlich lassen sich Tabellen mit Gültigkeitszeiträumen auch mit herkömmlichen, d. h. nicht-temporalen SELECT-Anweisungen abfragen. DB2 führt solche Abfragen in der gewohnten Weise aus. Ein Beispiel zeigt, wie einfach sich zeitbezogene Abfragen mit dem Konzept Business Time formulieren lassen. Die Tabelle POLICY enthält nun die in Tabelle 13 gezeigten Daten. Es sind dieselben, die auch Tabelle 10 [1] zeigt, unmittelbar nachdem wir die Tabelle POLICY erzeugt und vier Sätze eingefügt hatten. Für Abfragen nach temporalen Daten muss auch hier, analog zu Abfragen mit System Time, eine von drei unterstützten Zeitraumangaben in die FROM-Klausel aufgenommen werden. Die Zeitangaben können sowohl in der Vergangenheit als auch in der Zukunft sein:

FOR SYSTEM_TIME AS OF ...
FOR SYSTEM_TIME FROM ... TO ...
FOR SYSTEM_TIME BETWEEN ... AND ...

Mit folgender SQL-Anweisung lassen sich die für Police 1414 vom 1. Januar 2009 bis zum 1. Januar 2011 geltenden Versicherungsbedingungen abfragen:

SELECT *
  FROM policy
  FOR BUSINESS_TIME FROM '2009-01-01' TO '2011-01-01'
  WHERE id = 1414;

Temporale Abfragen an Tabellen mit Gültigkeitszeiträumen werden intern umgesetzt in WHERE-Klauseln für die DATE- oder TIMESTAMP-Spalten, in denen die Start- und Endzeitpunkte der Gültigkeitsdauer abgelegt sind.

Bitemporale Tabellen

Bitemporale Tabellen ermöglichen die Datenhaltung mit Bearbeitungs- und Gültigkeitszeit und die Ausnutzung der Vorzüge beider Konzepte. So lässt sich die Gültigkeitszeit für die Abbildung logischer Aspekte eines Datenbestands nutzen, wie beispielsweise die Laufzeiten von Versicherungspolicen und die Bearbeitungszeit zur Nachverfolgung der Änderungen, die an diesen Policen vorgenommen wurden. Die in Listing 6 dargestellte CREATE TABLE-Anweisung definiert eine bitemporale Tabelle mit einer Periode für BUSINESS_TIME in den Spalten bus_start und bus_end sowie mit einer Periode für SYSTEM_TIME in den Spalten sys_start und sys_end. Nach dem Erzeugen der bitemporalen Tabelle muss eine gleiche History-Tabelle erzeugt und Versionierung aktiviert werden.

CREATE TABLE policy (
  id              INT NOT NULL,
  vin             VARCHAR(10),
  annual_mileage  INT,
  rental_car      CHAR(1),
  coverage_amt    INT,
  bus_start       DATE NOT NULL,
  bus_end         DATE NOT NULL,
  sys_start       TIMESTAMP(12) GENERATED ALWAYS AS ROW BEGIN NOT NULL,
  sys_end         TIMESTAMP(12) GENERATED ALWAYS AS ROW END NOT NULL,
  trans_start     TIMESTAMP(12) GENERATED ALWAYS
                             AS TRANSACTION START ID IMPLICITLY HIDDEN,
  PERIOD SYSTEM_TIME (sys_start, sys_end),
  PERIOD BUSINESS_TIME(bus_start, bus_end),
  PRIMARY KEY(id, BUSINESS_TIME WITHOUT OVERLAPS)

Views

DB2 stellt für temporale Tabellen zwei Arten von Views zur Verfügung. Solche Views ermöglichen ein flexibles Anwendungsdesign, um bezogen auf eine Datenbanksitzung die Daten für unterschiedliche Zeitpunkte oder Perioden abzubilden.

  1. Views können für eine temporale Tabelle mithilfe einer FOR SYSTEM_TIME- oder FOR BUSINESS_TIME-Klausel definiert werden, um die Sicht auf einen bestimmten Zeitpunkt oder Zeitraum zu beschränken. Anschließend können diese Views mit herkömmlichen SQL-Anweisungen abgefragt werden. Abfragen an solche Views dürfen keine FOR SYSTEM_TIME- oder FOR BUSINESS_TIME-Klauseln enthalten, weil die zeitliche Bedingung in der Abfrage mit der zeitlichen Bedingung für die Views im Widerspruch steht oder zu zweideutigen Ergebnissen führen könnte.
  2. Definition einer View für eine temporale Tabelle ohne eine FOR SYSTEM_TIME- oder FOR BUSINESS_TIME-Bedingung: Solche Views stellen Daten für alle Zeitpunkte dar und lassen sich mit Anweisungen abfragen, die FOR SYSTEM_TIME- oder FOR BUSINESS_TIME-Klauseln enthalten. Solche Klauseln werden dann automatisch auf alle Tabellen in der View-Definition angewendet, die Perioden für System Time oder Business Time enthalten.

DB2 bietet damit enorme Flexibilität bei der Arbeit mit Views und temporalen Daten. Temporale Bedingungen lassen sich also in der View-Definition oder in Abfragen an Views von temporalen Tabellen nutzen.

Globale Einstellungen über Registervariablen

Neue Registereinstellungen bieten die Möglichkeit, Datenbestände mit vorhandenen Anwendungen von einem bestimmten Zeitpunkt aus zu analysieren, ohne dass die Anwendung selbst geändert werden muss. Im Folgenden geht es um eine Anwendung, die zahlreiche SQL-Abfragen oder bestimmte Berichtsabfragen enthält, die von Zeit zu Zeit ausgeführt werden müssen. Mit den temporalen Funktionen in DB2 wird man solche Abfragen auch für Bearbeitungszeitpunkte ausführen können, die in der Vergangenheit liegen, oder für vergangene oder künftige Gültigkeitszeiten. Müsste man nun jedoch alle vorhandenen SQL-Anweisungen um eine FOR SYSTEM_TIME- oder FOR BUSINESS_TIME-Klausel erweitern, wäre das möglicherweise sehr zeitaufwändig. Gleiches gilt für das Erzeugen von Views für alle betroffenen temporalen Tabellen. Deshalb stellt DB2 spezielle Register zur Verfügung, mit denen eine Datenbanksitzung auf einen spezifischen Zeitpunkt eingestellt werden kann. Beispiel: Mit folgendem SET-Befehl wird die Systemzeit der eigenen Sitzung auf den 1. Januar 2008, 10.00 Uhr, eingestellt:

SET CURRENT TEMPORAL SYSTEM_TIME = '2008-01-01 10:00:00';

Nun werden alle in dieser Datenbanksitzung an temporale (oder bitemporale) Tabellen gerichteten Abfragen für die Bearbeitungszeit 1. Januar 2008, 10.00 Uhr, ausgeführt. Oder anders ausgedrückt: Alle Abfragen in dieser Datenbanksitzung werden automatisch um die Klausel FOR SYSTEM_TIME AS OF ‚2008-01-01 10:00:00‘ erweitert. DB2 führt dies automatisch aus. Mit folgender Registereinstellung lassen sich die Daten für einen Zeitpunkt auswerten, der einen Monat vor der aktuellen Bearbeitungszeit liegt:

SET CURRENT TEMPORAL SYSTEM_TIME = current timestamp – 1 MONTH;

Steht im Register CURRENT TEMPORAL SYSTEM_TIME ein anderer Wert als NULL, sind Datenänderungen wie ändern, einfügen oder löschen an temporalen Tabellen unzulässig. Für Business Time lässt sich die Registervariable CURRENT TEMPORAL BUSINESS_TIME setzen, um Abfragen, Änderungen, Löschungen usw. an zurückliegenden oder künftigen Gültigkeitszeitpunkten vorzunehmen.

Fazit

Die neuen temporalen Funktionen von DB2 ermöglichen auf einfache Weise sowohl die differenzierte Auswertung historischer Datensätze als auch die Verfolgung zeitlicher Änderungen. Auf Grundlage der temporalen Erweiterungen des SQL-2011-Standards bietet DB2 eine innovative Umgebung für effektive temporale Datenhaltung, die im Vergleich zu selbst entwickelten Lösungen zur Abbildung temporaler Konzepte in Form von Triggern, Prozeduren oder selbst entwickelten Anwendungen ganz erhebliche Zeit- und Kostenvorteile bietet.

Links & Literatur
[1] Alle Beispieltabellen finden Sie auf www.entwickler-magazin.de
[2] Cynthia M. Saracco, Matthias Nicola, Lenisha Gandhi: „A matter of time: Temporal data management in DB2 10“
[3] DB2 auf IBM developerWorks (Technische Artikel, Software, Forum): http://www.ibm.com/developerworks

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -