Was ist die beste Vorgehensweise für die Darstellung von Zeitintervallen in einem Data Warehouse?

8

Insbesondere habe ich es mit einer sich langsam ändernden Dimension zu tun und muss das Zeitintervall angeben, das ein bestimmter Datensatz war aktiv für, dh für jeden Datensatz habe ich ein StartDate und ein EndDate . Meine Frage ist, ob eine geschlossene ( [StartDate, EndDate] ) oder halb offene ( [StartDate, EndDate) <) verwendet werden soll / em>) Intervall, um dies darzustellen, dh ob das letzte Datum in das Intervall aufgenommen werden soll oder nicht. Um ein konkretes Beispiel zu nennen, sei der Satz 1 vom ersten bis zum fünften Tag aktiv und der zweite Tag wurde aktiv. Mache ich das EndDate für Datensatz 1 gleich 5 oder 6?

Kürzlich bin ich zu der Art und Weise gekommen, zu denken, dass halboffene Intervalle am besten darauf basieren, unter anderem Dijkstra:Warum die Nummerierung bei Null beginnen sollte sowie die Konventionen für das Array-Slicing und die Funktion range () in Python. Wenn ich dies im Data Warehousing-Kontext anwende, sehe ich die Vorteile einer halboffenen Intervallkonvention wie folgt:

  • EndDate-StartDate gibt die Uhrzeit an, zu der der Datensatz aktiv war
  • Validierung: Das StartDate des nächsten Datensatzes entspricht dem EndDate des vorherigen Datensatzes, der leicht zu validieren ist.
  • Future Proofing: Wenn ich später beschließe, meine Granularität von täglich auf etwas kürzer zu ändern, bleibt das Umstellungsdatum immer noch genau. Wenn ich ein geschlossenes Intervall verwende und das EndDate mit einem Zeitstempel von Mitternacht speichere, müsste ich diese Datensätze entsprechend anpassen.

Deshalb würde ich eine halboffene Intervallmethode bevorzugen. Wenn es jedoch eine weit verbreitete Branchenkonvention der Verwendung der Closed-Interval-Methode gäbe, könnte ich mich eher darauf einlassen, insbesondere wenn sie auf praktischen Erfahrungen bei der Implementierung solcher Systeme und nicht auf meiner abstrakten Theorie basiert.

Vielen Dank im Voraus für Einsichten oder Kommentare.

    
snth 24.11.2010, 08:57
quelle

3 Antworten

9

Ich habe sowohl geschlossene als auch halboffene Versionen gesehen. Ich bevorzuge aus den von Ihnen genannten Gründen halb geöffnet.

Meiner Meinung nach macht die halboffene Version das beabsichtigte Verhalten klarer und ist "sicherer". Das Prädikat (a & lt; = x & lt; b) zeigt deutlich, dass b außerhalb des Intervalls liegen soll. Wenn Sie dagegen geschlossene Intervalle verwenden und in SQL angeben (x BETWEEN a UND b), dann wird die falsche Antwort erhalten, wenn jemand das Enddatum einer Zeile unklugerweise als Anfang der nächsten verwendet.

Setzen Sie das späteste Enddatum standardmäßig auf das größte Datum, das Ihr DBMS unterstützt, und nicht auf Null.

    
sqlvogel 24.11.2010, 10:57
quelle
5

Im Allgemeinen stimme ich Davids Antwort zu (Abstimmung), also werde ich diese Information nicht wiederholen. Außerdem:

Meinst du wirklich halboffen ([StartDate, EndDate])

?

Sogar in diesem "halboffenen" gibt es zwei Fehler. Einer ist ein direkter Normalisierungsfehler, der natürlich doppelte Daten implementiert, die Sie in der Diskussion identifizieren, die als abgeleitete Daten verfügbar sind und die entfernt werden sollten.

  • Für mich ist Half Open (StartDate)
  • EndDate wird von der nächsten Zeile abgeleitet.
  • es ist die beste Vorgehensweise
  • es ist keine gebräuchliche Verwendung, weil (a) gewöhnliche Implementierer sich dieser Tage nicht bewusst sind und (b) sie zu faul sind oder nicht wissen, wie sie die notwendige einfache Unterabfrage programmieren sollen
  • basiert auf Erfahrung in großen Bankdatenbanken

Einzelheiten hierzu finden Sie unter

Link zur letzten sehr ähnlichen Frage & amp; Datenmodell

Antworten auf Kommentare

  

Sie scheinen normalisierte Designs eindeutig mit natürlichen, sinnvollen Schlüsseln zu bevorzugen. Ist es gerechtfertigt, in einem Reporting Data Warehouse davon abzuweichen? Nach meinem Verständnis ist der zusätzliche Platz für Ersatzschlüssel und doppelte Spalten (z. B. EndDate) ein Kompromiss für erhöhte Abfrageleistung. Einige meiner Kommentare über die Cache-Nutzung und die Erhöhung der Festplatten-IO lassen mich dies jedoch in Frage stellen. Ich wäre sehr interessiert an Ihrem Beitrag dazu.

  1. Ja. Absolut. Jeder vernünftige Mensch (der Informatik nicht aus dem Wiki lernt) sollte das in Frage stellen. Es widerspricht einfach den Gesetzen der Physik.

  2. Kannst du verstehen, dass viele Leute, ohne Normalisierung oder Datenbanken zu verstehen (du brauchst 5NF), unnormalisierte langsame Datenhaufen produzieren, und ihre berühmte Entschuldigung (von "Gurus" geschrieben) ist "denormalized for Performance"? Jetzt weißt du, dass es Exkremente sind.

  3. Dieselben Leute, ohne Normalisierung oder Datawarehouses zu verstehen (Sie brauchen 6NF), (a) erstellen Sie eine Kopie der Datenbank und (b) alle möglichen seltsamen und wunderbaren Strukturen, um Abfragen zu "verbessern" einschließlich (c) noch mehr Vervielfältigungen. Und rate mal, was ihre Entschuldigung ist? "für die Leistung denormalisiert".

    • Es ist kriminell, und die "Gurus" sind nicht besser, sie bestätigen es.

    • Ich würde sagen, dass diese "Gurus" nur "Gurus" sind, weil sie eine pseudo-wissenschaftliche Grundlage bieten, die die Nicht-Wissenschaft der Mehrheit rechtfertigt.

    • Falsche Informationen werden nicht wahrer, wenn sie wiederholt werden, und Gott weiß, dass sie es ad infinitum wiederholen .

  4. Die einfache Wahrheit (nicht komplex genug für Leute, die Datawarehouses mit (1) (2) (3) rechtfertigen) ist, dass 6NF richtig ausgeführt wird, ist das Data Warehouse. Ich biete sowohl Datenbank als auch Data Warehouse aus denselben Daten mit Lagergeschwindigkeit. Kein zweites System; keine zweite Plattform; keine Kopien; kein ETL; keine Kopien synchronisiert halten; keine Benutzer müssen zu zwei Quellen gehen. Sicher, es erfordert Geschick und ein Verständnis von Leistung und ein wenig speziellen Code, um die Einschränkungen von SQL zu überwinden (Sie können 6NF in DDL nicht angeben, Sie müssen einen Katalog implementieren).

    • Warum ein StarSchema oder ein SnowFlake implementieren, wenn die reine Normalized-Struktur bereits volle Dimension-Fakt-Fähigkeit besitzt.
      .
  5. Auch wenn Sie das nicht getan haben, wenn Sie nur die traditionelle Sache gemacht und diese Datenbank auf ein separates Datawarehouse-System ETLed haben, würde es schneller laufen, wenn Sie Dubletten, reduzierte Zeilengröße und reduzierte Indizes eliminieren würden. Ansonsten widerspricht es den Gesetzen der Physik: Dicke Menschen würden schneller rennen als dünne Menschen; eine Kuh würde schneller laufen als ein Pferd.

    • Fair genug, wenn Sie keine normalisierte Struktur haben, dann bitte alles, um zu helfen. Also haben sie StarSchemas, SnowFlakes und alle möglichen Dimension-Fact-Designs.

Und bitte verstehen Sie, nur unqualifizierte, unerfahrene Leute glauben all diese Mythen und Magie. Gebildete erfahrene Leute haben ihre hart verdienten Wahrheiten, sie stellen keine Hexendoktoren ein. Diese "Gurus" bestätigen nur, dass die fette Person das Rennen wegen des Wetters oder der Sterne nicht gewinnt; alles aber die Sache, die das Problem lösen wird. Ein paar Leute bekommen ihre Schlüpfer in einem Knoten, weil ich direkt bin, sage ich der fetten Person, Gewicht zu verlieren; aber der wahre Grund, warum sie sich aufregen, ist, dass ich ihre hochgeschätzten Mythen durchbohre, dass sie gerechtfertigt sind, fett zu sein. Leute mögen es nicht, sich zu ändern.

  • Eine Sache. Ist es jemals gerechtfertigt, abzuweichen ? Die Regeln sind nicht schwarz-weiß; Sie sind keine einzelnen Regeln isoliert. Eine denkende Person muss alle zusammen betrachten; priorisieren Sie sie für den Kontext.Sie werden weder alle Id iot Schlüssel noch null Id iot Schlüssel in meinen Datenbanken finden, aber jeder Id Schlüssel wurde sorgfältig geprüft und begründet.

    • Verwenden Sie auf jeden Fall die kürzest möglichen Schlüssel, aber verwenden Sie sinnvolle Relationale über Surrogate; und verwenden Sie Surrogates, wenn der Schlüssel zu groß zum Tragen wird.

    • Aber fang niemals mit Surrogaten an. Dies beeinträchtigt Ihre Fähigkeit, die Daten zu verstehen, erheblich. Normalisieren; modelliere die Daten.

      • Hier ist eine ▶ Frage / Antwort ◀ (von vielen!), wo die Person in diesem Prozess steckengeblieben war und nicht einmal die grundlegenden Entitäten und Relationen identifizieren konnte, weil er zu Beginn alle Id iot Schlüssel festgeklebt hatte. Problem gelöst ohne Diskussion, in der ersten Iteration.
        .
  • Ok, noch etwas. Lernen Sie dieses Thema, sammeln Sie Erfahrungen und fördern Sie sich selbst. Aber versuche nicht, es zu lehren oder andere zu konvertieren, auch wenn die Lichter brennen und du eifrig bist. Vor allem, wenn Sie begeistert sind. Warum ? Denn wenn du den Rat eines Zauberdoktors in Frage stellst, wird dich das ganze Dorf lynchen, weil du ihre geschätzten Mythen angreifst, ihre Bequemlichkeit; und Sie brauchen meine Art von Erfahrung, um Hexendoktoren zu nageln (überprüfen Sie einfach Beweise in den Kommentaren!). Gib es ein paar Jahre, hol dir deine wirklich hart erkämpfte Erfahrung und nimm sie dann weiter.

Wenn Sie interessiert sind, folgen Sie dieser ▶ Frage / Antwort ◀ für ein paar Tage wird es ein großartiges Beispiel dafür sein, wie man die IDEF1X-Methodik befolgt, wie man diese Identifikatoren entlarvt und destilliert.

    
PerformanceDBA 27.11.2010 04:55
quelle
0

Nun, der Standard sql where my_field between date1 and date2 ist inklusive, also bevorzuge ich die inklusive Form - nicht dass der andere falsch ist.

Die Sache ist, dass diese ( rowValidFrom, rowValidTo ) Felder für gewöhnliche DW-Abfragen meistens überhaupt nicht verwendet werden, da der Fremdschlüssel in einer Faktentabelle bereits auf die entsprechende Zeile in der Dimensionstabelle zeigt.

Diese werden hauptsächlich beim Laden benötigt (wir sprechen hier von Typ 2 SCD), um den aktuellsten Primärschlüssel für den passenden Geschäftsschlüssel zu suchen. An diesem Punkt haben Sie etwas wie:

%Vor%

Oder wenn Sie vor dem Laden eine Schlüssel-Pipeline erstellen möchten:

%Vor%

Dies hilft beim Laden, weil es einfach ist, die Schlüsseltabelle vor dem Laden in den Speicher zwischenzuspeichern. Wenn beispielsweise ProductName varchar (40) und ProductKey eine Ganzzahl ist, beträgt die Schlüsseltabelle weniger als 0,5 GB pro 10 Millionen Zeilen und kann einfach zum Nachschlagen zwischengespeichert werden.

Andere häufig gesehene Variationen sind were rowIsCurrent = 'yes' und where rowValidTo is null .

Im Allgemeinen werden eines oder mehrere der folgenden Felder verwendet:

  • rowValidFrom
  • rowValidTo
  • rowIsCurrent
  • rowVersion

abhängig von einem DW-Designer und manchmal ETL-Werkzeug, da die meisten Werkzeuge einen SCD-Ladeblock Typ 2 haben.

Es scheint Bedenken hinsichtlich des Speicherplatzes zu geben, den zusätzliche Felder haben - daher werde ich hier die Kosten für die Verwendung von etwas zusätzlichem Platz in einer Dimensionstabelle schätzen, wenn aus keinem anderen Grund als Bequemlichkeit.

Angenommen, ich verwende alle Zeilenfelder.

%Vor%

Dies ergibt 15 Bytes. Man kann argumentieren, dass dies 9 oder sogar 12 Bytes zu viel ist - OK.

Bei 10 Millionen Zeilen entspricht dies 150.000.000 Bytes ~ 0.14GB

Ich habe die Preise von einer Dell-Website nachgeschlagen.

%Vor%

Ich werde Raid 5 hier (drei Laufwerke) annehmen, also wird der Plattenpreis 0,078 $ / GB * 3 = 0,23 $ / GB

betragen

Also, für 10 Millionen Zeilen, um diese 4 Felder auf den Festplattenkosten zu speichern 0.23 $/GB * 0.14 GB = 0.032 $ . Wenn die gesamte Dimensionstabelle in den Speicher zwischengespeichert werden soll, wäre der Preis dieser Felder 38 $/GB * 0.14GB = 5.32 $ pro 10 Millionen Zeilen. Im Vergleich kostet ein Bier in meiner lokalen Kneipe ~ 7 $.

Das Jahr ist 2010, und ich erwarte, dass mein nächster Laptop über 16 GB Speicher verfügt. Dinge und (beste) Praktiken ändern sich mit der Zeit.

BEARBEITEN:

Hat die Suche in den letzten 15 Jahren die Kapazität eines durchschnittlichen Computers um das 1000-fache, den des Speichers um das 250-fache erhöht?

    
Damir Sudarevic 01.12.2010 15:41
quelle