Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Historische Datenhaltung

Begonnen von MartinHan, Januar 25, 2025, 14:56:53

⏪ vorheriges - nächstes ⏩

Bitsqueezer


PhilS

Zitat von: MartinHan am Januar 31, 2025, 00:04:12Natürlich haben wir Sicherungen, als Db-Backup, aber bei aller Geneigheit, ich werde die jetzt nicht wieder einzeln laden, den Kunden entfernen und ein neues Backup ersatellen.

[...]
Frage beantworted?
Es war nicht direkt eine Frage, "beantwortet" ist sie allerdings nicht.
Das Magnetband/Backup-Szenario wurde mit Inkrafttreten der DSGVO häufig angeführt und diskutiert. - Aus meiner Sicht eher unnötig.

1.) Mit einer gesetzlichen Aufbewahrungsfrist kannst du ein Löschersuchen nach DSGVO zurückweisen.
2.) Daten in einem Backup sind natürlich noch gespeichert, aber sie sind nicht mehr in der aktiven Verarbeitung und werden dieser auch nicht wieder zugeführt, ausser evtl. in einem außergewöhnlichen, sicherlich dokumentierten, Disaster-Recovery-Fall. Nach Ablauf einer definierten Aufbewahrungsfrist, egal ob gesetzlich oder firmenintern, werden sie dann automatisch gelöscht.

Solange deine Historientabellen ein rein technisches Audit-Log sind, könnte man da noch ähnlich argumentieren. Insbesondere wenn es auch dort eine begrenzte Aufbewahrungsfrist gibt.


Dein aktuelles Vorhaben, so wie ich es im Moment verstehe, ist es aber diese Historientabellen den Benutzern direkt für Auswertungen zugänglich zu machen. - Wenn du das tust, ändert sich die Rolle der Historientabellen von einen technischen Audit-Log zu einer aktiven Verarbeitung.
Aus der aktiven Verarbeitung musst du Daten auf ein Löschersuchen nach DSGVO hin aber durchaus löschen, wenn dem nicht direkt rechtliche Pflichten widersprechen.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

MzKlMu

Hallo,
jetzt komm ich wieder mit meiner Meinung um die Ecke.  :)

Wenn ich mir den Aufwand betrachte, den Martin für diese Historientabellen aufwendet, so bin ich nach wie vor der Auffassung, dass ein normalisierter Aufbau der DB viel, viel geeigneter ist historische Daten abzubilden, als das aufwendige Konstrukt mit den Historientabellen.

Was die DSGVO so habe ich dazu mal eine Frage an die Experten:
Wenn die DB normalisiert aufgebaut ist, so gibt es die Personendaten in genau einer Tabelle. Wenn jetzt jemand seine Daten gelöscht haben will, würde es da nicht genügen in der Personentabelle die echten Personendaten mit z.B. XXXX zu überschreiben ?
Würde da das Überschreiben (XXXX) nur des Nachnamens nicht schon genügen.
Die Originaldaten sind ja dann unwiederbringlich weg (von Backups mal abgesehen). Und alle Tabelle mit einem Fremdschlüssel zur Person können uneingeschränkt benutzt werden, ohne dass es einen Bezug gibt zur Person.
Würde das nicht ausreichen ?
Gruß Klaus

PhilS

Zitat von: MzKlMu am Januar 31, 2025, 10:03:13Wenn die DB normalisiert aufgebaut ist, so gibt es die Personendaten in genau einer Tabelle. Wenn jetzt jemand seine Daten gelöscht haben will, würde es da nicht genügen in der Personentabelle die echten Personendaten mit z.B. XXXX zu überschreiben ?
Eher nein.
Erstmal müsstest du sicherstellen, dass nirgends sonst Daten gespeichert sind, die Rückschlüsse auf die Identität der Person zulassen (TelNr, Email, Kontonummern, Adressen, usw.). Insbesondere Freitext/Kommentar-Felder sind ein unterschätztes Risiko, weil da oft auch Personendaten drinstehen.
Auch eigentlich neutrale Informationen, wie Z.B. eine Kundennummer, sind problematisch, wenn sie zusammen mit zuvor erstellen Dokumenten (Geschäftsbriefe, Rechnung, etc.) Rückschlüssel auf die Identität zulassen.
Man könnte generell argumentieren, dass eine Kundennummer dadurch dass sie einem Kunden zugewiesen wurde, dauerhaft, also auch wenn die anderen Kundendaten überschrieben sind, als Personenbezogenes Datum im Sinne der DSGVO gilt.

Nur den Nachnamen zu überschreiben reicht definitiv nicht aus.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

MartinHan

Hallo,
also der Aufwand für die Historientabellen hält sich doch sehr in Grenzen.
Ich muss für jede Tabelle, die historisiert werden soll eine Historientabelle mit den identischen Spalten wie die ursprüngliche anlegen. Dann mit "alter Table" zwei Datetime2 Spalten an die unsprüngliche Tabelle anfügen und den Prozess aktivieren. Wenn man erstmal verstanden hat wie es geht, Sache von Minuten.
Dann im Access FE einige Abfragen oder über ein StP auf die Historie einrichten, auch das ist relativ einfach.
Dann kann man natürlich Auswertungen verfassen, bis ich meinen letzten Atemzug mache, also z.B. über "Schülerwanderungen", also wieviele sind von einem Grundkurs zu einem Fortgeschrittenen Kurs "gewandert", da ist noch vieles denkbar.
Was die rechtliche Seite angeht bin ich noch unsicher. Wir haben alle Kursänderungen auch schriftlich in Form von Vertragsänderungen in Papierform, die Daten liegen also vor. In allen diesen Vertragsänderungen steht das Passus, das der Kunde mit der Speicherung der Daten nur für den internen Gebrauch einverstanden ist.
Es ist bis jetzt noch nicht zu einem Rechtsstreit gekommen, knock on wood...
Das Löschen der Daten aus Historientabellen ist auch nicht ganz trivial. ich lese mich da noch ein.
Es gibt aber wohl einen Parameter der dazu führt, das die historischen Daten nach einem definierten Zeitraum automatisch gelöscht werden. Das werde ich mir noch anschauen.

Aber ich teste noch weiter.

Martin

Es gibt nichts gutes, außer, man tut es! EK

MartinHan

Hi,

das mit dem Komplett-Löschen der Daten habe ich jetzt verstanden und auch schon getestet.
Man muss bei allen beteiligten Tabellen

SYSTEM_VERSIONING = OFF

setzen, dann sind die Historischen Tabellen wie ganz normale Tabellen.
Dann die Löschung durch führen und danach wieder

SYSTEM_VERSIONING = ON

Dann ist die Person komplett gelöscht.
q.e.d

Martin


Es gibt nichts gutes, außer, man tut es! EK

MartinHan

Hallo Christian,

nach einigen Tagen in stiller Askese und Programmierung bin ich ich doch zu der Überzeugung gekommen, dass die Temporalen Tabellen doch eine gute Lösung sind.
Würde ich das selbst machen, liefe es doch auf stwas ähnliches hinaus, ich muss speichern, von wann bis wann ein Datensatz gültig war, ich wüßte nicht, wie es sonst gehen sollte.
Nichts anderes machen die temporalen, bzw. historischen Tabellen...
Nur das das ganze Geraffel von der DB erledigt wird, von mir keine einzelne Zeile Coding, finde ich gut.
Ich bin jetzt dabei in meinem Access-Fe Abfragen und Auswertungen zu entwicklen, klappt prima!

Ich hatte mir selbst ein Archiv-System bebastelt, das kann ich ietzt in die Tonne kloppen.

Danke für deine Beiträge!

Martin
Es gibt nichts gutes, außer, man tut es! EK

Bitsqueezer

Hallo Martin,

alles gut - wenn es für Dich paßt, warum nicht?
Am besten testest Du mal die Historien-Tabellen mit Auswertungsabfragen - denn sie sollen ja nicht dem Selbstzweck dienen, Du möchtest daraus ja Informationen gewinnen.

Dann kann man am ehesten sehen, ob sie für Dich das leisten, was Du Dir davon erhofft hast.

Gruß

Christian

MartinHan

Hallo,

ein für mich unerklärliches Phänomen:

Wenn ich einen Datensatz ändere, wird ja ein historischer DS erzeugt und die validvon bzw. validbis Felder angepasst.
Das klappt auch soweit, nur ist das Datum der Änderung eine Stunde zurück...
Der Server ist für die Entwicklung lokal installiert, die Systemzeit passt.

So habe ich die Historisierung definiert (bei einer schon bestehenden Tabelle)

/****** Object:  Table [history].[Person]    Script Date: 21.01.2025 17:15:25 ******/
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[history].[Person]') AND type in (N'U'))
DROP TABLE [history].[Person]
GO

/****** Object:  Table [History].[Person]    Script Date: 21.01.2025 17:15:25 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [history].[Person](
    [PersonId] [int] NOT NULL,
    [NachName] [nvarchar](255) NULL,
    [Vorname] [nvarchar](255) NULL,
    ---weitere Spalten ....
    ValidFrom DATETIME2(0) NOT NULL,
    ValidTo DATETIME2(0) NOT NULL,
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[person]
    ADD ValidFrom datetime2(0) GENERATED ALWAYS AS ROW START HIDDEN
        CONSTRAINT DF_person_SysStart DEFAULT DATEADD(second, -1, SYSUTCDATETIME()),
    ValidTo datetime2(0) GENERATED ALWAYS AS ROW END HIDDEN
        CONSTRAINT DF_person_SysEnd DEFAULT CONVERT(datetime2 (0), '9999-12-31 23:59:59'),
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
GO

ALTER TABLE [dbo].person
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [History].person));

GO

CREATE NONCLUSTERED INDEX IX_person_ID_Period_Columns
ON History.person (ValidTo, ValidFrom,personid);
GO

Danke für Hilfe

Martin
Es gibt nichts gutes, außer, man tut es! EK

Bitsqueezer

Hallo Martin,

das Problem ist, daß SQL Server UTC Time verwendet.
Die Lösung ist "AT TIME ZONE" zu verwenden, wie hier beschrieben:
https://learn.microsoft.com/en-us/sql/relational-databases/tables/temporal-table-usage-scenarios?view=sql-server-ver16&redirectedfrom=MSDN

Gruß

Christian

MartinHan

oh my Buddha, ein endloser Artikel...
Bitte in Kurzform...
was much ich ändern?
Es gibt nichts gutes, außer, man tut es! EK

Bitsqueezer

Hallo Martin,

suche auf der Seite einfach nach "AT TIME ZONE", dann findest Du die passenden Beispielcodes.

Gruß

Christian

MartinHan

Ok, habe ich jetzt verstanden.
Danke.
Es gibt nichts gutes, außer, man tut es! EK