Nicht übereinstimmende Datenquelle für Header und Werbebuchung

7

Ich arbeite mit einem Sternschema für ein Data Warehouse und habe ein Problem mit Kopf- und Werbebuchungen aus verschiedenen Datenquellen.

CREATE TABLE DataSourceAHeader
(
     OrderId INT NOT NULL
    ,TotalCost MONEY NOT NULL
    -- Date, etc...
);

CREATE TABLE DataSourceALine
(
     OrderId INT NOT NULL
    ,LineNumber INT NOT NULL
    -- Dates, etc...
);

CREATE TABLE DataSourceBLine
(
     OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    ,LineNumber INT NOT NULL
);

Ich habe Datenquellen A und B, die dieselben Daten auf unterschiedliche Weise darstellen. Datenquelle A enthält Kopfzeilen und Werbebuchungen, enthält jedoch nur das Nettoergebnis (Gesamtkosten) in der Kopfzeile. Datenquelle B enthält nur Werbebuchungen und jede Position hat ein Ergebnis (Kosten).

Ich konnte zwei Faktentabellen halten (eine für den Kopf und eine für die Einzelposten), aber ich habe recherchiert und es scheint nicht ratsam. Gibt es eine Strategie, um mit dieser Art von nicht übereinstimmendem Format umzugehen, oder sollten sie in separaten Data Warehouses gespeichert werden (ein Warehouse pro Datenquelle)?

Meine aktuelle Strategie:

CREATE TABLE Fact.Order
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    -- Date key, etc...
);

CREATE TABLE Fact.OrderLine
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderFactId BIGINT NOT NULL REFERENCES Fact.Order (Id)
    ,LineNumber INT NOT NULL
    -- related line stuff
);

DataSourceAHeaderund DataSourceBLinewerden in Orderund eingefügt OrderLine. DataSourceBLinewird eine Zeile pro Zeile aufgeteilt.

Hier ist ein Beispiel für ein DataSourceAHeaderundDataSourceALine

SELECT * FROM Fact.Order;
|------------------------------------|
|   Id   |   OrderId   |   Cost      |
|   1    |     1100    |   12000.00  |
|   2    |     1101    |   10000.00  |
|------------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        1        |       2        |
|   3    |        1        |       3        |
|   4    |        2        |       1        |
|   5    |        2        |       2        |
|   6    |        2        |       3        |
|-------------------------------------------|

Hier ist ein Beispiel für a DataSourceBLine

SELECT * FROM Fact.Order;
|---------------------------------|
|   Id   |   OrderId   |   Cost   |
|   1    |     1000    |   12.00  |
|   2    |     1000    |   10.00  |
|---------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        2        |       2        |
|-------------------------------------------|

Bearbeiten:

Das TotalCostin der Kopfzeile kann nicht auf die Zeilenebene gebracht werden. Ich unterhielt mich mit einem Bekannten des Architekten und sein Rat war, zwei separate Faktentabellen zu implementieren, eine für die Kopfzeile (Zusammenfassung) und eine für die Zeilen (Detail), und nur NULLWerte für die fehlenden Zeileninformationen für zu haben DataSourceA.

Edit2:

Ich versuche, generisch mit der OrderId umzugehen, da ich mehrere weitere Datenquellen habe, die ähnliche OrderId-Schemata (Kollisionen) enthalten können. Ich habe eine Zuordnungstabelle implementiert, um die Quellkennungen in das Warehouse zu übersetzen.

Edit3:

Mit der Absicht, dass diese Frage nicht nur für mich selbst hilfreich ist, möchte ich, dass die Antwort die folgenden Details enthält (hauptsächlich, um zusammenzustellen, worüber alle bereits nachgedacht haben):

  • Welche Ansätze gibt es im Allgemeinen, um verwandte disjunkte Datensätze in Form von Zusammenfassungen / Details (einzelne Faktentabelle oder Zusammenfassung / Detail-Faktentabellen) aufzulösen?
  • Was sind die Nachteile jedes Ansatzes?
  • Welche Struktur könnte die Faktentabelle annehmen, um mit fehlenden (oder irrelevanten) Daten umzugehen?
  • (Zwei-Fakten-Tabellen-Ansatz) In welchen Fällen wäre es ratsam, die Zusammenfassung herunterzurollen, anstatt die Details aufzurollen?
Dustin Kingen
quelle
Wie planen Sie basierend auf dem vorgeschlagenen Modell, die Werbebuchung Kostenwerte für Daten aus Datenquelle A (neu) zu erstellen? Scheint unmöglich, wenn keine zusätzlichen Informationen verfügbar sind (Produkt, Einheit, Menge usw.).
Jon Seigel
Ja, es ist unmöglich, die Werbebuchung Kostenwerte zu rekonstruieren. Im Moment behandle ich die Linien als Dimensionstabelle und trenne die Linien von DataSourceBLine. Jede Werbebuchung wird zu einer separaten Zeile.
Dustin Kingen
@ JonSeigel Überprüfen Sie meine Bearbeitung der Frage.
Dustin Kingen
Oh, tut mir leid, ich habe übersehen, dass Sie gesagt haben, dass beide Datenquellen dieselben Daten darstellen.
Jon Seigel
Okay, um klar zu sein, fragen Sie sich, wie Sie das Laden des im Artikel empfohlenen "abgeflachten" Nur-Zeilen-Schemas implementieren können. Richtig?
Jon Seigel

Antworten:

4

Wenn Sie dies in eine einzelne Faktentabelle de-normalisieren möchten, handelt es sich in der Faktentabelle um Werbebuchungen. Daher müssen die Fakten von DataSourceAHeader aufgeteilt und an die entsprechenden Werbebuchungen verteilt werden, damit sie nicht dupliziert werden. Wie es derzeit dargestellt wird, bedeutet dies, dass Sie Ihre gesamten Bestellkosten senken und diese durch Summieren der Werbebuchungskosten berechnen.

Die DataSourceAHeader-Dimensionsschlüssel (z. B. Bestelldatum) können aus DataSourceAHeader entnommen und auf die aus DataSourceBLine generierten Faktenzeilen angewendet werden. Im Beispiel scheinen in DataSourceALine keine Informationen enthalten zu sein, die weder in DataSourceAHeader noch in DataSourceBLine bereits enthalten sind. Wenn dies jedoch der Fall ist, können diese auf ähnliche Weise zugeordnet werden.

Dieser Ansatz beruht auf einer Reihe von Annahmen. Die wichtigste ist, dass alle Fakten von DataSourceAHeader genau auf die einzelnen Werbebuchungen verteilt werden können. Wenn dies nicht der Fall ist, ist das Laden von zwei separaten Faktentabellen (eine für die Bestellung und eine für die Werbebuchungen) möglicherweise ein besserer Ansatz. Das Gleiche gilt möglicherweise, wenn viele Fragen zu Bestellungen gestellt werden müssen, bei denen keine Einzelposten-spezifischen Informationen berücksichtigt werden. Dies wird in dem Artikel, auf den Sie verwiesen haben, als "Bad Idea # 2" bezeichnet, aber ich habe festgestellt, dass es unter bestimmten Umständen tatsächlich eine gute Idee ist.

Schließlich wird davon ausgegangen, dass die beiden Datenquellen synchron sind. Wenn dies nicht der Fall ist, beschränken Sie sich darauf, Daten im Tempo der langsameren Datenquelle zu laden. Dies mag in Ordnung sein, muss jedoch im Kontext Ihrer Anforderungen und des Unterschieds zwischen den beiden Datenquellen berücksichtigt werden.

Bearbeiten: Die De-Normalisierung in eine einzelne Faktentabelle kann die Leistung beim Zählen von Aufträgen erheblich beeinträchtigen, da es sich im Wesentlichen um eine eindeutige Zählung handelt. Dies wäre mein Hauptgrund für die Berücksichtigung von zwei separaten Faktentabellen.

Bearbeiten 2 (als Antwort auf die Frage bearbeiten):

Hier besteht das Problem darin, dass auf der detailliertesten Ebene (Linien-) Daten unvollständig sind, da nicht alle Zeilen einen Kostenwert haben. Die Gesamtkosteninformationen sind jedoch auf der nächsthöheren Ebene (Kopfzeile) verfügbar. Dies stellt die Situation dar, in der Sie die höhere Ebene nicht von der niedrigeren ableiten können. Betrachten wir die resultierenden Optionen:

  1. Halten Sie eine einzelne Faktentabelle mit der niedrigsten verfügbaren Granularität bereit (Zeile). Dies ist kein Anfänger, da wir uns jetzt auf die unvollständigen Leitungsdaten verlassen, um Fragen auf der höheren Ebene zu beantworten, von denen wir wissen, dass wir sie hätten beantworten können.
  2. Haben Sie eine einzelne Faktentabelle mit der höheren Granularität (Header). Dies bedeutet, dass wir jetzt Fragen auf der höheren Ebene mit den vollständigen Daten beantworten können, aber Fragen auf der detaillierteren Ebene überhaupt nicht mehr beantworten können. Dies kann als akzeptabel angesehen werden, aber in den meisten Fällen werfen wir potenziell wertvolle Daten weg.
  3. Haben Sie zwei verwandte Faktentabellen, eine für die unvollständigen, detaillierteren Daten (Zeile) und eine für die vollständigen, weniger detaillierten Daten (Header). Dies ist die ideale Lösung, da wir jetzt Fragen auf der höheren Ebene vollständig beantworten und Fragen auf der niedrigeren Ebene aufgrund der Unvollständigkeit der Quelldaten bestmöglich beantworten können.

Diese Frage wurde aufgrund von Zweifeln an zwei verwandten Faktentabellen aufgeworfen. Die Zweifel ergeben sich aus der Tatsache, dass das Verwalten und Verbinden von zwei großen Faktentabellen ressourcenintensiv sein kann. Das stimmt, und wenn Ihre detailliertesten Informationen verwendet werden können, um eine vollständige Beschreibung der Situation bereitzustellen, ist die Verwendung einer einzelnen Faktentabelle vorzuziehen. In solchen Situationen, in denen dies nicht möglich ist, sind jedoch zwei Faktentabellen erforderlich, wenn Sie so viele Informationen wie möglich aufbewahren möchten.

Matt
quelle
Ihr eindeutiger Zählpunkt ist gültig. Es gibt jedoch verschiedene Möglichkeiten, ihn zu optimieren, ohne dass Daten dupliziert werden müssen. Es wäre ein harter Kampf, der mich davon überzeugen würde, dass die Zuweisung in den allermeisten Fällen nicht der richtige Ansatz ist, wenn zwei Faktentabellen vorhanden sind.
StrayCatDBA
all the facts from DataSourceAHeader can accurately be distributed among its constituent line itemsDas DataSourceAHeaderkann nicht auf die Zeilen verteilt werden, daher denke ich, dass zwei separate Tabellen benötigt werden. Siehe meine Bearbeitung der Frage unten.
Dustin Kingen
Wenn das bei Romoku der Fall ist, würde ich den beiden Tabellen zustimmen. Es ist definitiv nicht inakzeptabel, wenn Sie die anderen Optionen untersucht und festgestellt haben, dass sie nicht passen.
Matt
2

Beginnen wir mit der Annahme, dass Sie nur eine Faktentabelle für "Bestellungen" benötigen. Dieser Ansatz ist in 99% der Fälle korrekt und Ihr Szenario ist ziemlich normal.

  1. Deklarieren Sie den Gewinn der Faktentabelle: Eine Zeile pro Bestellposition.

  2. Bestimmen Sie die Dimensionsattribute (Bestelldatum, Versanddatum, Kunde, Produkt usw.). Diese sind eine Mischung aus Bestellkopf und Bestellposition. Die Bestellnummer (Order.OrderId?) Wird zu einer "entarteten Dimension" (Sie haben keine Dimension "Bestellungen", da alle interessanten Attribute bereits entfernt wurden und nur die Bestellnummer übrig bleibt.)

  3. Bestimmen Sie die Fakten. Dies sind die mit der Bestellung verbundenen Messungen. Menge, Kosten, Umsatz usw. Sie möchten dann additiv bleiben, also Menge und erweiterten Preis speichern, nicht Preis pro Stück. Messungen, die nur auf Kopfebene existieren, müssen der Zeilenebene zugeordnet werden.

Wenn das Unternehmen zögert, die Kosten auf Auftragsebene der Werbebuchung zuzuordnen, ist das schade. Sie erhalten ein besseres Data Warehouse, wenn sie dies tun.

StrayCatDBA
quelle
Das TotalCostin der Kopfzeile kann nicht auf die Zeilenebene gebracht werden. Ich unterhielt mich mit einem Bekannten des Architekten und sein Rat war, zwei separate Faktentabellen zu implementieren, eine für die Kopfzeile (Zusammenfassung) und eine für die Zeilen (Detail), und nur NULLWerte für die fehlenden Zeileninformationen für DataSourceA(Zeile Cost) zu haben.
Dustin Kingen
Warum können die Gesamtkosten nicht nach unten verteilt werden? Was ist die Begründung gegeben? Was ist der Unterschied zwischen den Gesamtkosten und der Summe der Leitungskosten?
StrayCatDBA
Es kann nicht verteilt werden, da DataSourceAes keine Leitungskosten (nur Leitungsinformationen) oder eine Methode zum Ableiten der Leitungskosten gibt. Ich erhalte diese Daten wie sie sind und kann den Anbieter leider nicht zwingen, sein System zu ändern.
Dustin Kingen
Entspricht dieselbe orderId beiden Datenquellen oder handelt es sich um disjunkte Systeme? Oder wird die Bestellung 223344, wenn sie von DataSourceA stammt, auch in DataSourceB angezeigt?
StrayCatDBA
Ja, es kann zu Kollisionen kommen. Ich habe eine Zuordnungstabelle implementiert, um die Quellkennungen in das Lager zu übersetzen
Dustin Kingen
0

Versuchen Sie, sich von beliebigen Primärschlüsseln zu entfernen. Bei Bestellungen gibt es einen nützlichen Schlüssel in der Bestellnummer. Die Zeilennummern sind auch in Kombination mit der Bestellnummer eindeutig. Beim Laden der Daten sollten Ausnahmen wie Duplikate abgefangen werden.

Alle Ihre primären und ausländischen Einschränkungen für die von Ihnen freigegebenen Daten müssen auf der Bestellnummer und der Zeilennummer basieren, wobei die Mitte des Sterns den Auftragskopf und die Gesamtkosten sowie die Werbebuchungen in einer separaten Tabelle mit den zugehörigen Kosten und anderen Daten enthält aus beiden Quellen in diskreten Spalten

Paddy Carroll
quelle
Ich versuche, generisch mit dem zu sein, OrderIdda ich mehrere weitere Datenquellen habe, die ähnliche OrderIdSchemata (Kollisionen) enthalten können. Ich habe eine Zuordnungstabelle implementiert, um die Quellkennungen in das Warehouse zu übersetzen.
Dustin Kingen