Im Jahr 2017 haben wir die Linkstruktur mit einem Beispiel für ein Data Vault-Modell im Bankensektor. Wir haben gezeigt, wie das Modell aussieht, wenn eine Verbindung entweder eine Beziehung oder eine Transaktion zwischen zwei Geschäftsobjekten darstellt. Ein Link kann auch mehr als zwei Hubs miteinander verbinden. Darüber hinaus gibt es einen Sonderfall, bei dem sich ein Teil der in einem Link gespeicherten Hub-Referenzen ändern kann, ohne eine andere Beziehung zu beschreiben. Dies hat einen großen Einfluss auf die Link-Satelliten. Was ist die Alternative zur Implementierung des Driving Key in Data Vault 2.0?
Der Fahrschlüssel
Eine Beziehung oder Transaktion wird oft durch eine Kombination von Geschäftsschlüsseln in einem Quellsystem identifiziert. In Data Vault 2.0 wird dies als normaler Link modelliert, der mehrere Hubs verbindet, die jeweils einen Geschäftsschlüssel enthalten. Ein Link enthält auch seine eigene Hash-Schlüsselder über die Kombination aller geschäftlichen Schlüssel der Eltern berechnet wird. Wenn also die Verknüpfung vier Hubs verbindet und sich ein Geschäftsschlüssel ändert, weist der neue Datensatz einen neuen Verknüpfungs-Hash-Schlüssel auf. Es gibt ein Problem, wenn vier Geschäftsschlüssel die Beziehung beschreiben, aber nur drei von ihnen sie eindeutig identifizieren. Wir können das Geschäftsobjekt nicht identifizieren, indem wir nur den Hash-Schlüssel der Verknüpfung verwenden. Das Problem ist kein Modellierungsfehler, sondern wir müssen bei der Abfrage der Daten den richtigen Datensatz im zugehörigen Satelliten identifizieren. In Data Vault 2.0 wird dies als Antriebsschlüssel bezeichnet. Es handelt sich um einen konsistenten Schlüssel in der Beziehung und oft um den Primärschlüssel im Quellsystem.
Die folgenden Tabellen zeigen die Beziehung zwischen einem Mitarbeiter und einer Abteilung aus einem Quellsystem.
Aus dieser Ausgangsstruktur lässt sich das folgende Data Vault-Modell ableiten.
Die Verknüpfungstabelle "Empl_Dep" wird von der Tabelle "Employee" im Quellsystem abgeleitet. Der treibende Schlüssel in diesem Beispiel ist die Mitarbeiternummer, da sie der Primärschlüssel in der Quelltabelle ist und ein Mitarbeiter nur in einer Abteilung zur gleichen Zeit arbeiten kann. Das bedeutet, dass der wahre treibende Schlüssel im Satelliten des Mitarbeiters "lebt". Wenn die Abteilung eines Mitarbeiters wechselt, gibt es keinen zusätzlichen Datensatz in der Satellitentabelle des Mitarbeiters, sondern einen neuen in der Verknüpfungstabelle, was legitim ist.
Um das jüngste Delta abzufragen, müssen Sie es in der Verknüpfungstabelle abfragen, gruppiert nach dem Fahrschlüssel.
Zusammenfassend lässt sich sagen, dass Sie immer einen neuen Link-Hash-Schlüssel haben werden, wenn sich ein Geschäftsschlüssel in einer Beziehung ändert. Die Herausforderung besteht darin, den treibenden Schlüssel zu identifizieren, der ein eindeutiger Geschäftsschlüssel (oder eine Kombination von Geschäftsschlüsseln) für die Beziehung zwischen den verbundenen Knotenpunkten ist. Manchmal muss man ein zusätzliches Attribut hinzufügen, um einen eindeutigen Bezeichner zu erhalten.
Beides stellt ein Problem für Power-User dar, die Zugriff auf das Modell Data Vault haben. Ohne Benennungskonventionen besteht die Gefahr, dass eine Gruppierung nach mehr Attributen als nur dem treibenden Schlüssel durchgeführt wird, was zu unerwarteten und falschen Gesamtwerten führen würde - auch wenn die Daten selbst korrekt modelliert sind.
Beim Umgang mit Beziehungsdaten gibt es eine bessere Lösung als den Antriebsschlüssel: Wir bevorzugen in der Regel die Modellierung solcher Daten als nicht-historisierte Verbindung und fügen Sie technische Gegentransaktionen zu den Daten ein, wenn sich eine Hub-Referenz ändert.
Im Falle eines geänderten Datensatzes in der Quelle fügen wir zwei Datensätze in die nicht-historisierten Verknüpfungen ein: einen für die neue Version des geänderten Datensatzes in der Quelle und einen für die alte Version, die noch im Ziel existiert (nicht-historisierte Verknüpfung), aber jetzt gekontert werden muss - den technischen Gegensatzsatz. Zur Unterscheidung der Datensätze aus der Quelle und den Gegengeschäften wird eine neue Spalte eingefügt, die oft "Zähler" genannt wird.
Der Standardwert für dieses Zählerattribut ist 1 für Datensätze aus der Quelle und -1 für die technischen Gegengeschäfte. Wichtig: Wir führen keine Aktualisierungsanweisungen durch, sondern fügen nur die neuen Zählersätze ein. Wenn Sie die Kennzahlen aus der Verknüpfung abfragen, multiplizieren Sie die Kennzahlen einfach mit dem Zählerwert.
Die Tabelle 3 zeigt eine Verknüpfung mit einem Zählerattribut. Wenn sich ein Datensatz im Quellsystem ändert, wird er mit dem ursprünglichen Wert und einem Zählerwert von -1 in die Link-Tabelle des data warehouse eingefügt. Für den geänderten Wert gibt es einen neuen Link-Hash-Schlüssel, der ebenfalls über das beschreibende Attribut "Salary" berechnet wird. Der Zählerwert des neuen Satzes ist 1.
Schlussfolgerung
Da die Identifizierung des treibenden Schlüssels einer Beziehung in manchen Situationen ein Problem darstellen kann, können Sie eine alternative Lösung verwenden, um den treibenden Schlüssel zu vermeiden. Alle Änderungen und Löschungen werden mit Hilfe eines Zählerattributs in der nicht-historisierten Verknüpfungstabelle nachverfolgt. Sie speichert auch die beschreibenden Attribute, und der Link-Hash-Schlüssel wird über alle Attribute berechnet.
Updates und Support erhalten
Bitte senden Sie Anfragen und Funktionswünsche an [email protected].
Für Anfragen zu Data Vault-Schulungen und Schulungen vor Ort wenden Sie sich bitte an [email protected] oder registrieren Sie sich unter www.scalefree.com.
Um die Erstellung von Visual Data Vault-Zeichnungen in Microsoft Visio zu unterstützen, wurde eine Schablone implementiert, die zum Zeichnen von Data Vault-Modellen verwendet werden kann. Die Schablone ist erhältlich bei www.visualdatavault.com.
Hallo zusammen, wenn ich das Konzept der Datenaktualisierung in der Verknüpfung richtig verstehe, sollten im zweiten und dritten Datensatz dieses Beispiels in Tabelle 3 genau die Ladedaten stehen. Denn wenn sich ein Datensatz im Quellsystem ändert, wird diese neue Information geladen und die vorherige gleichzeitig "ungültig" gemacht. Liege ich da richtig?
Hallo Tomas,
Zunächst führen wir keine "physischen" Aktualisierungen in der Verbindung durch, sondern erstellen neue Datensätze, die "Zählersätze" sind. Die Genauigkeit des Ladedatums hängt von der Häufigkeit der Datenladungen ab. Bei täglichen Batch-Ladungen könnte der Tag als detailliertester Wert ausreichen. Bei Mini-Batches sollten Sie mindestens die Sekunden angeben. Und ja, das Einfügen neuer Datensätze und das Einfügen der Zähler können parallel laufen.
Mit freundlichen Grüßen,
Scalefree Mannschaft
Hallo scalefree Team,
Könnten Sie bitte ein Beispiel aus dem wirklichen Leben nennen, bei dem der erläuterte Ansatz von Vorteil war?
Mit freundlichen Grüßen,
Mike
Hallo Mike,
Wir verwenden diesen Ansatz in Situationen, in denen wir volle Prüfbarkeit bei gleichzeitiger Einfachheit benötigen. Wir haben diesen Ansatz bei Berenberg erfolgreich bei den Buchungsvorgängen der Bank eingesetzt. In diesem Fall war die Bank in der Lage, in der Historie aller Transaktionen vor und zurück zu blättern, um jederzeit den aktuellen Stand aller Bankkonten abzurufen. Mehr Details: Erfolgsgeschichte Berenberg & Scalefree
Mit freundlichen Grüßen,
Ihr Scalefree-Team
Hinweis: Der Artikel wurde am 14. Januar 2019 zur Verbesserung der Qualität überarbeitet.
Es gibt immer noch einen Fehler in der Tabelle 3. Der zweite (Korrektur-)Datensatz sollte den Wert 2013-07-14 2:11:10 Load_Date haben.
Außerdem muss ich empfehlen, den Gehaltswert direkt mit -1 zu multiplizieren, um die Summe zu vereinfachen.
Hallo Richard,
wir wollen den ursprünglichen Datensatz rückgängig machen, deshalb verwenden wir genau die gleichen Werte wie beim ersten Datensatz (der Zählerwert ist Teil des LinkHashKey). In Abfragen müssen Sie mit dem Zählerattribut multiplizieren, ja.
Mit freundlichen Grüßen,
Ihr Scalefree-Team
Hallo,
Ich habe das Gefühl, dass die einzige Stelle, von der man das erfahren kann, eine CDC ist... Ich verstehe nicht, wie man die -1 erstellen kann, ohne zu wissen, dass sich die Beziehung von Abteilung A zu Abteilung B geändert hat....
Wenn ja, was passiert bei einem Wechsel in die Abteilung C...
Ich kann mir vorstellen, dies von einem Änderungsauslöser aus zu tun, wo ich jetzt zwei Insert Statements in den Link erstellen kann... aber nicht in einem Batch Load oder von einer CDC-Änderung aus, da ich nicht wüsste, wo ich in der CDC aufgehört habe...
Danke,
Hallo John,
Ja, wenn möglich, sind CDC-Audit-Trails definitiv der richtige Weg. Wenn CDC/Audit Trails in der Quelle implementiert sind, sollten Sie sich für Standard Link und seine Satelliten entscheiden. Unsere Lösung hängt von der vollständigen Datenübermittlung ab. Ziel ist es, für jede Änderung einen vollständigen Zählersatz des ursprünglichen Datensatzes zu erstellen.
Wir verwenden zwei verschiedene Muster für den gesamten Prozess. Das erste ist eine Einfügeanweisung, die neue oder geänderte Datensätze einfügt (gekennzeichnet durch den Link_Unique_HK).
Das zweite Muster fügt die Zählerbuchung ein, wenn Datensätze in der Verknüpfung nicht im transienten Staging-Bereich (oder beim letzten Batch-Load in einem persistenten Staging-Bereich) vorhanden sind. Beide Prozesse können parallel ablaufen.
Mit freundlichen Grüßen,
Ihr Scalefree-Team
Hallo,
Wie würde man anhand von Tabelle 3 den Stand vom 2013-07-04 02:00:00 abfragen?
Benötigen Sie dazu nicht auch das Load_Date der Änderung?
Herzliche Grüße,
Tjomme
Hallo Tjomme,
das Load_Date und die Record Source sind nicht Teil des eindeutigen Hash-Schlüssels. Die Erkennung erfolgt über einen vollständigen Tabellenscan im Staging-Bereich (in dem Sie die vollständige Datenladung aus dem Quellsystem haben), indem der eindeutige Hash-Schlüssel verglichen wird. Das Load_Date ist in diesem Fall nicht das Ladedatum für den Zählerdatensatz, da es nie wirklich existiert. Der Zählerdatensatz ist der ursprüngliche erste Datensatz und wird zur gleichen Zeit/im gleichen Stapel wieder eingefügt, wenn die neuen Datensätze geladen werden, nur mit dem Zähler -1. Am 2013-07-04 02:00:00 existiert der Zählerdatensatz noch nicht. Er wird eingefügt, wenn der dritte Datensatz eingefügt wird.
Remember, that this method should be used if you don’t receive CDC data, but full data delivery only.
Mit freundlichen Grüßen,
Ihr Scalefree-Team
Hi Karina,
A purpose of the Data Vault is auditability. This means that today we should be able to reproduce the status of the source system as it was on 2013-07-14 02:00:00.
When only working with the table 3 above, this will be a challenge. Or am I missing something?
This will become a lot easier when the Load_Date of the record causing the counter record to be created is captured on the counter record as well. In this case that would be 2013-07-14 02:11:10. By filtering on this field, we would be able to set the table to any point in time easily.
Or is this information maintained in a (not mentioned) status satellite?
The same technique could be used when processing CDC logs as well.
Herzliche Grüße,
Tjomme
Hi Tjomme,
yes, you’re right.
You can only reproduce the original data delivery when you set the load date for the counter record to the date from the current data load where you actually recognize it is missing. We changed that accordingly.
Thanks for your eagle eye and best regards,
Ihr Scalefree-Team
I have 2 questions:
1) I assume Link_Unique_HK in given example has to be calculated based on Employee BK, Department BK, Counter and Load_date. It has to be unique, and the employee may enter same department multiple times, right?
2) If we can mix relationship and contextual data in transactional link, could we also mix relationship and contextual data in sattelite? For given example the table structure would be the same, just the table would represent sattelite of employee hub. So primary key would be employee_hk and load_date. We could also calculate Link_unique_hk just based on Employee_hk and department_hk like in standard empl_dep link. I believe we could even create view for virtualizing that link on top of such satellite, so there will be physical representation of empl_dep link in database. We would need just one new row per change. Regarding loading full dumps as well as CDC can be leveraged. Power users and ETL for datamarts would retrieve current records like from standard satellite and few joins may be left. Can you point out any pitfalls you can see regarding this approach?
Hello Karel,
1) Correct.
2) Your approach is similar to that, which involves Driving Keys. However, in this case, you’ll NEED a Link to set Business Keys in relation, what is also part of the standards of Data Vault 2.0 for several reasons – but this is another topic. Keep in mind, that the approach you suggest would work for a one-to-many relationship, but not for a many-to-many relationship as you would need to activate multiple LDTS per Hash Key.
The situational issue here is, when the business key in a relationship has changed and you don’t have an audit trail, which informs you about that. The result would be a new Link entry with a new Link Hash Key (which is ok) and another Satellite entry (which is ok as well), however you’ll have to soft delete the “old” entries (or however you mark disappearing data in your Data Warehouse).
This forces you to perform a full table scan of the Stage table to figure out, which Business Key relations have disappeared. This can be handled in various ways: create a Record Tracking or Effectivity Satellite hanging on the Link; utilize the Driving Key approach; or – the more “straight-forward” way – keep just one Non-Historized Link table and simply counter the whole record as soon as it’s disappeared from the source.
Mit freundlichen Grüßen,
Ihr Scalefree-Team
There are a few problems with this approach
1) modelling attributes into a link is inflexible to schema evolution — if another attribute is to be added the entire history of the link needs to be considered.
2) if the driving key for the relationship changes then you will need to model a new link
3) non-historised links are exception loading patterns, they are reserved for immutable data that is not expected to change – such as transactions coming in at real-time. Non-historised links are made for speed layer (lambda) where data is not staged.
4) modelling the details as a link is far more effective but adding a counter would mean you have derived data – i.e. it is a business rule and thus something you add to business vault. Non-historised links are not business vault artefacts.
5) how do you deal with a relationship that has returned? i.e. the the employee has returned to his original department.
This flexibility is effectively (pun intended) handled in creating effectivity satellites based on the driving keys of a link. If the driving key changes then the link remains but a new effectivity satellite is created. Effectivity satellites are derived; each new relationship per driving key is given a highdate as an end-date. Each change to that relationship in relation to non-driving key keys of that relationship generates a close record and a new active record (highdate). All of it is insert only. Querying the data is flexible too, pick your driving key(s) (there may be more than one) and select the data from the effectivity satellite based on the date you’re after and you can trace the number of times the relationship has changed.
You can even trace when the relationship was lost. i.e. a null was presented from source for the non-driving key business keys making it a zero key and we can easily trace that through this construct. Effectivity satellites need a driving key and are all about the relationship and not the contextual information for that relationship. i.e the column salary would sit in a link-sat for that relationship and not in the effectivity satellite. If start and end dates are provided by the source system then this is a regular satellite and not an effectivity satellite.
Hi Patrick,
thank you for your feedback. Here are my 2 cents on your challenges:
1) you could just add a non-historized satellite to the existing link to capture additional entities without reloading and restating the link data
2) non-historized links should not be used to capture relationships (like employee to manager) but instead focus on transactions and events. I have to admit, I’m not a big fan of the driving key concept and to be honest – avoid it like the pest. Which means that I try to find a better solution for a driving key (in a non-historized link, that is a counter-transaction).
3) not necessarily. We used it with banks (for example) to capture booking transactions that were loaded in batches via stage. In other words: every entity (hubs, standard links, non-historized links and any satellite) can be loaded in batch, near-realtime or “actual” realtime.
4) Any entity type can be part of the Business Vault. The difference between Raw Data Vault and Business Vault is that the Raw Data Vault contains raw, unmodified data, while the Business Vault contains calculated, pre-processed data. For the Raw Data Vault, the question is: can you re-construct the delivery as it was delivered from the source? We can, even with the technical counter transactions. Therefore it meets the Raw Data Vault definition (but I have to admit, it is a border case).
5) Again, I would not use non-historized links to capture relationships. Use a standard link in combination with an effectivity satellite to capture the business driven “employement start and end-date”.
I hope that clarifies it a bit.
Mike
Very interesting approach I like it. One thing I haven’t wrapped my head around yet is: where do we get the BK for the changing HK(s) for (not part of the driving key, in this article the Department BK) , to calculate the Unique Hash key for the counter transaction? From the hub(s)?
Hi Johan,
thank you very much!
In this case, you don’t need the Business Key. Keep in mind that this is a possible approach if no audit trail is provided by the source system, which means that you have to do a complete lookup back into the staging to figure out whether or not a Link Hash Key (the most recent record) still exists. If not, you create the “counter booking”, based on the Link itself with the counter value -1.
Ich hoffe, das hilft.
Mit freundlichen Grüßen,
Ihr Scalefree-Team