Ich bin mir ziemlich sicher, dass viele Anwendungen, kritische Anwendungen, Banken usw. dies täglich tun.
Die Idee dahinter ist:
- Alle Zeilen müssen einen Verlauf haben
- Alle Links müssen kohärent bleiben
- Es sollte einfach sein, Anfragen zu stellen, um "aktuelle" Spalten zu erhalten
- Kunden, die veraltete Produkte gekauft haben, sollten weiterhin sehen, was sie gekauft haben, obwohl dieses Produkt nicht mehr im Katalog enthalten ist
und so weiter.
Hier ist, was ich tun möchte, und ich erkläre die Probleme, mit denen ich konfrontiert bin.
Alle meine Tabellen haben diese Spalten:
id
id_origin
date of creation
start date of validity
start end of validity
Und hier sind die Ideen für CRUD-Operationen:
- erstelle = füge eine neue Zeile mit
id_origin
=id
,date of creation
= now,start date of validity
= now,end date of validity
= null ein (= bedeutet, es ist der aktuell aktive Datensatz) - update =
- read = liest alle Datensätze mit
end date of validity
== null - Aktualisiere den "aktuellen" Datensatz
end date of validity
= null mitend date of validity
= now - erstelle einen neuen mit den neuen Werten und
end date of validity
= null (= bedeutet, es ist der aktuell aktive Datensatz)
- read = liest alle Datensätze mit
- delete = Aktualisiere den "aktuellen" Datensatz
end date of validity
= null mitend date of validity
= now
Also hier ist mein Problem: mit vielen zu vielen Assoziationen. Nehmen wir ein Beispiel mit Werten:
- Tabelle A (id = 1, id_origin = 1, start = now, end = null)
- Tabelle A_B (start = now, end = null, id_A = 1, id_B = 48)
- Tabelle B (id = 48, id_origin = 48, start = now, end = null)
Jetzt möchte ich Tabelle A aktualisieren, Datensatz-ID = 1
- Ich markiere die Datensatz-ID = 1 mit end = now
Ich füge einen neuen Wert in Tabelle A ein und ... verdammt, ich habe meine Beziehung A_B verloren, es sei denn, ich dupliziere auch die Beziehung ... dies würde zu einer Tabelle führen:
Tabelle A (id = 1, id_origin = 1, start = now, end = now + 8mn)
- Tabelle A (id = 2, id_origin = 1, start = now + 8mn, end = null)
- Tabelle A_B (start = now, end = null, id_A = 1, id_B = 48)
- Tabelle A_B (start = now, end = null, id_A = 2, id_B = 48)
- Tabelle B (id = 48, id_origin = 48, start = now, end = null)
Und ... nun, ich habe ein anderes Problem: die Beziehung A_B: soll ich (id_A = 1, id_B = 48) als veraltet markieren oder nicht (A - id = 1 ist veraltet, aber nicht B - 48)?
Wie gehe ich damit um?
Ich muss das in großem Maßstab gestalten: Produkte, Partner und so weiter.
Welche Erfahrungen haben Sie damit gemacht? Wie würden Sie tun (wie haben Sie getan)?
- Bearbeiten
Ich habe diesen sehr interessanten Artikel gefunden , aber er befasst sich nicht richtig mit "Cascasding Obsolescence" (= was ich eigentlich frage)
quelle
Antworten:
Mir ist nicht klar, ob diese Anforderungen zu Prüfungszwecken oder nur als einfache historische Referenz dienen, z. B. für CRM und Einkaufswagen.
In beiden Fällen sollten Sie eine Haupt- und eine Hauptarchivtabelle für jeden Hauptbereich in Betracht ziehen, in dem dies erforderlich ist. "Main" hat nur aktuelle / aktive Einträge, während "main_archive" eine Kopie von allem hat, was jemals in main geht. Einfügen / Aktualisieren in Hauptarchiv kann ein Auslöser für das Einfügen / Aktualisieren in Hauptarchiv sein. Löschvorgänge für main_archive können dann ggf. über einen längeren Zeitraum ausgeführt werden.
Bei referenziellen Problemen wie Cust X, das Produkt Y gekauft hat, können Sie Ihr referenzielles Problem mit cust_archive -> product_archive am einfachsten lösen, indem Sie niemals Einträge aus product_archive löschen. Im Allgemeinen sollte die Abwanderung in dieser Tabelle viel geringer sein, damit die Größe kein Problem darstellt.
HTH.
quelle
LP_
, und jede einzelne wichtige Tabelle hat ein ÄquivalentLH_
, wobei Trigger historische Zeilen beim Einfügen, Aktualisieren und Löschen einfügen. Es funktioniert nicht in allen Fällen, aber es war ein solides Modell für die Dinge, die ich tue.UNION
Ansicht erstellen können , mit denen Sie beispielsweise eine eindeutige Einschränkung für aktuelle und historische Datensätze erzwingen können.id
" und "id_ref
" habe.id_ref
ist ein Verweis auf die eigentliche Idee der Tabelle. Beispiel:person
undperson_h
. inperson_h
Ich habe "id
" und "id_ref
" woid_ref
steht mit 'person.id
' in Beziehung , so dass ich viele Zeilen mit dem gleichen haben kannperson.id
(= wenn eine Zeile vonperson
geändert wird) undid
alle meine Tabellen sind autoinc.Dies hat einige Überschneidungen mit der funktionalen Programmierung; speziell das Konzept der Unveränderlichkeit.
Sie haben einen Tisch angerufen
PRODUCT
und einen anderen angerufenPRODUCTVERSION
oder ähnlich. Wenn Sie ein Produkt ändern und kein Update durchführen, fügen Sie einfach eine neuePRODUCTVERSION
Zeile ein. Um die neueste Version zu erhalten, können Sie die Tabelle nach Versionsnummer (absteigend), Zeitstempel (absteigend) oder Kennzeichen (LatestVersion
) indizieren .Wenn Sie etwas haben, das auf ein Produkt verweist, können Sie entscheiden, auf welche Tabelle es verweist. Verweist es auf die
PRODUCT
Entität (bezieht sich immer auf dieses Produkt) oder auf diePRODUCTVERSION
Entität (bezieht sich nur auf diese Version des Produkts)?Es wird kompliziert. Was ist, wenn Sie Bilder des Produkts haben? Sie müssen auf die Versionstabelle verweisen, da sie geändert werden können. In vielen Fällen werden sie dies jedoch nicht tun und Sie möchten Daten nicht unnötig duplizieren. Das heißt, Sie brauchen einen
PICTURE
Tisch und einePRODUCTVERSIONPICTURE
Beziehung von vielen zu vielen.quelle
Ich habe all das Zeug von hier mit 4 Feldern implementiert , die sich auf allen meinen Tabellen befinden:
Jedes Mal, wenn ein Datensatz geändert werden muss, dupliziere ich ihn. Markiere den duplizierten Datensatz als "alt" =
date_validity_end=NOW()
und den aktuellen als den gutendate_validity_start=NOW()
unddate_validity_end=NULL
.Der Trick handelt von den vielen zu vielen und eins zu vielen Beziehungen: Es funktioniert, ohne sie zu berühren! Es geht nur um die komplexeren Abfragen: Um einen Datensatz an einem bestimmten Datum (= nicht jetzt) abzufragen , muss ich für jeden Join und für die Haupttabelle die folgenden Einschränkungen hinzufügen:
Also mit Produkten und Attributen (viele zu viele Relationen):
quelle
Wie wäre es damit? Es scheint einfach und ziemlich effektiv für das, was ich in der Vergangenheit getan habe. Verwenden Sie in Ihrer "Verlaufstabelle" eine andere PK. Ihr "CustomerID" -Feld ist also die PK in Ihrer Kundentabelle, aber in der "history" -Tabelle ist Ihre PK "NewCustomerID". "CustomerID" wird nur ein weiteres schreibgeschütztes Feld. Dadurch bleibt "CustomerID" im Verlauf unverändert, und alle Ihre Beziehungen bleiben bestehen.
quelle