Versionierung von Datensätzen

ukulele

Datenbank-Guru
Beiträge
5.306
Ich archiviere derzeit monatlich einen Datenbestand aus einer Verwaltungs-Software. Die Software liefert mir mehrere Tabellen in einer Access DB, ca. 700 MB, 8 Tabellen und vieleicht 250 Spalten pro Archivierung. Um mit den Daten Auswertungen zu fahren importiere ich sie in meinen SQL Server (in diesem Fall MSSQL).

Bei den Daten handelt es sich um Auftrags- und Zeitdaten. Die Datensätze ändern sich selten, werden aber bei jedem Export komplett übergeben. Die Veränderungen betreffen eigentlich immer nur die laufenden Aufträge, sind dann irgendwann abgeschlossen und werden wie bereits mehrere zurückliegende Jahre einfach nur noch in der aktuellen Version aus der Software exportiert.

Ausgewertet wird nach Zeiträumen, pro Zeitraum mache ich einen Export und Import. Wenn ich jetzt jedesmal alle Daten mit ihrem aktuellen Datensatz in die DB schmeisse bläht sich das natürlich ganz ordentlich auf. Auch Datensätze die nicht von Veränderungen betroffen wären würden erneut gespeichert. Wenn ich es komplett zerlege so und nur die Atribute die sich ändern in Logtabellen schreibe habe ich die perfekt realtionale und speicherschonende Datenhaltung aber nen Riesenaufwand bei jeder Auswertung.

Als naheliegend empfand ich daher die Datensätze in layout-identische Tabellen zu überführen und mit Zeitstempel (import_datum) zu versehen. Ein neuer Datensatz wird nur dann generiert wenn sich etwas geändert hat. (Einmal erstellte Aufräge werden übrigens nie gelöscht.) Jetzt hat meine Auftragstabelle bei 3 Importen 19.989 verschiedene Aufträge und 21.595 Versionen (also Datensätze absolut).

Zum weiterarbeiten habe ich mir zwei Sichten erstellt. Einmal für den jeweils aktuellesten Datensatz zu jedem Auftrag und einmal für jeden Zeitstempel alle zugehörigen Datensätze, unabhängig davon ob sie sich geändert haben oder nicht. Heißt: Wenn ich einen Datensatz mit Zeitstempel 1 eingetragen habe und der beim nächsten Import festgestellt habe das er sich nicht verändert hat, gibt es ihn nur mit Zeitstempel 1. Meine sicht stellt ihn aber auch für Zeitstempel 2 mit den gleichen Daten wie in Datensatz 1 dar. Das kommt dann in Summe auf 57.593 Einträge, was exakt der Anzahl an Einträgen entsprechen müsste die ich erhalten hätte, wenn ich mit jedem Import alle Daten in die Tabelle geschrieben hätte.

Beispiel Auftragstabelle:
import_datum, pk, Auftragsnummer, Name
01.12.2013, 1, 201301, alter Auftrag
01.12.2013, 2, 201312, nicht ganz so alter Auftrag
01.01.2014, 2, 201312, nicht ganz so alter Auftrag geändert
01.01.2014, 3, 201401, neuer Auftrag

Anzeige aktueller Versionen (Sicht 1):
import_datum, pk, Auftragsnummer, Name
01.12.2013, 1, 201301, alter Auftrag
01.01.2014, 2, 201312, nicht ganz so alter Auftrag geändert
01.01.2014, 3, 201401, neuer Auftrag

Anzeige Versionsverlauf (Sicht 2):
01.12.2013, 1, 201301, alter Auftrag
01.01.2014, 1, 201301, alter Auftrag
01.12.2013, 2, 201312, nicht ganz so alter Auftrag
01.01.2014, 2, 201312, nicht ganz so alter Auftrag geändert
01.01.2014, 3, 201401, neuer Auftrag

Nun laufen meine Auswertungen eigentlich alle über die Sichten, je nachdem was ich grade brauche. Sicht 2 ist dabei nicht ganz einfach und ich wollte hier mal fragen ob jemand Optimierungspotenzial sieht.
Code:
SELECT    tdatum.import_datum,
        tdaten.*
FROM    (    SELECT    DISTINCT
                    import_datum
            FROM    [dbo].[datev_dbauftraege] ) tdatum
LEFT JOIN [dbo].[datev_dbauftraege] tdaten
ON        tdatum.import_datum = tdaten.import_datum
OR        tdatum.import_datum > tdaten.import_datum
AND NOT EXISTS (    SELECT    1
                    FROM    [dbo].[datev_dbauftraege]
                    WHERE    ANLAGEJAHR = tdaten.ANLAGEJAHR
                    AND        AUFTRAGSNUMMER = tdaten.AUFTRAGSNUMMER
                    AND        import_datum = tdatum.import_datum )
 
Werbung:

Code:
ON tdatum.import_datum = tdaten.import_datum
OR tdatum.import_datum > tdaten.import_datum

konnte wohl auch

Code:
ON tdatum.import_datum >= tdaten.import_datum

lauten, oder?


Ansonsten fände ich anstatt

Code:
Als naheliegend empfand ich daher die Datensätze in layout-identische Tabellen zu überführen und mit Zeitstempel (import_datum) zu versehen. Ein neuer Datensatz wird nur dann generiert wenn sich etwas geändert hat.

Einen TRIGGER bald noch naheliegender, der ein Changed-Flag setzt. Beim Export dann alle exportierten Flags rücksetzen.

Ansonsten hab ich nun nicht sooo genau geschaut, ich denk mal, Du weißt selbst besser, was du tust als ich...
 
Code:
ON tdatum.import_datum = tdaten.import_datum
OR tdatum.import_datum > tdaten.import_datum

konnte wohl auch

Code:
ON tdatum.import_datum >= tdaten.import_datum

lauten, oder?
hm ne, danach kommt ja noch AND NOT EXISTS, das bezieht sich ja nur auf tdatum.import_datum > tdaten.import_datum nicht auf tdatum.import_datum = tdaten.import_datum.

Das mit dem Trigger verstehe ich nicht richtig. Stand ist ja der das ich, wenn es einen neuen Datensatz gibt, dieser auch geändert wurde. Gibt es keinen (mit neuerem import_datum, aber ein neueres import_datum), ist er nicht geändert worden. Also ersetzt das vorhandensein des Datensatzes das Flag.

Allerdings bringt mich das auf eine Idee. Ich könnte mit jedem Import eine Tabelle mit import_datum des imports und allen zu dem Zeitpunkt gültigen Datensätzen füllen. Würde dann mit einem einfachen Join gehen.
 
Das mit dem Trigger verstehe ich nicht richtig. Stand ist ja der das ich, wenn es einen neuen Datensatz gibt, dieser auch geändert wurde. Gibt es keinen (mit neuerem import_datum, aber ein neueres import_datum), ist er nicht geändert worden. Also ersetzt das vorhandensein des Datensatzes das Flag.

Na, bestehende Datensätze, die geändert werden, bekommen via TRIGGER das Flag. Neue auch. Also da im Live-System. Beim Export nimmst alle die, die das Flag haben. Das dann rücksetzen. Somit bekommst nur neue / geänderte Datensätze (gemessen am letzten Export).
 
Achso, ne an die DB der exportierenden Anwenung komme ich derzeit nicht ran sonst könnte ich mir da direkt nen Log bauen oder dergleichen, ist aber leider verdongelt.
 
Werbung:
Zurück
Oben