Star-Schema-Modellierung - Zeitdimension
*Markus
- datenbank
Hallo,
ich habe eine Frage bezüglich des zeitlichen Mitloggens von Klicks. Die Klicks befinden sich in der Faktentabelle. Dimensionen sind Artikel, Hersteller, Kunden, und der Zeitpunkt. Die letztere beschert mir aber ein wenig Kopfzerbrechen. Wie soll man eine Dimensionstabelle mit Zeit erstellen, v.a. wofür steht dann der Primary Key dieser Tabelle? Eine Primary-Key-ID entspräche dann einem Tag, wenn ich pro Tag die Klicks zählen will? Heißt das, dass ich die Tabelle mit so vielen Einträgen vorbefüllen muss, wie ein Jahr Tage hat? Wie sieht das dann überhaupt mit Jahren aus? Ich müsste ja theoretisch wissen, wie lange die Website laufen wird, um schon mal entprechend viele Jahre "vorbefüllen" zu können?
Versteht ihr, was mein Problem dabei ist? Wie sieht die Lösung dazu aus? Ich möchte einfach sagen können wieviele Klicks ich pro Tag / Monat / Jahr zählte, über mehrere Jahre hinweg. Mir ist nicht klar, wie ich so eine Tabelle am besten befüllen soll.
Markus
Hi,
ich habe eine Frage bezüglich des zeitlichen Mitloggens von Klicks. Die Klicks befinden sich in der Faktentabelle. Dimensionen sind Artikel, Hersteller, Kunden, und der Zeitpunkt.
Mit Dimensionen meinst du Spalten?
Die letztere beschert mir aber ein wenig Kopfzerbrechen. Wie soll man eine Dimensionstabelle mit Zeit erstellen, v.a. wofür steht dann der Primary Key dieser Tabelle?
Der Primay Key, also üblicher Weise eine nummerische, fortlaufende ID - der muss für gar nichts "stehen". Seine Aufgabe ist, eine Zeile in der Tabelle eindeutig identifizierbar zu machen.
Wenn er noch eine andere Bedeutung angedacht bekommt - dann wird's normalerweise gefährlich.
Eine Primary-Key-ID entspräche dann einem Tag, wenn ich pro Tag die Klicks zählen will?
Aha, du willst also gar nicht einzelne Klicks speichern, sondern nur einen Zählerstand über einen bestimmten Zeitraum.
Dann könnte man u.U. eine Ausnahme machen, und das Datum als Primary Key benutzen.
Heißt das, dass ich die Tabelle mit so vielen Einträgen vorbefüllen muss, wie ein Jahr Tage hat?
Nein, warum solltest du?
Ich möchte einfach sagen können wieviele Klicks ich pro Tag / Monat / Jahr zählte, über mehrere Jahre hinweg. Mir ist nicht klar, wie ich so eine Tabelle am besten befüllen soll.
"Befülle" sie immer dann, wenn ein Klick auftritt - wenn es für das aktuelle Datum schon einen Eintrag gibt, dann erhöhe dessen Zählerstand um eins, sonst erstelle einen Eintrag für dieses Datum mit Zählerstand eins.
Wenn du bspw. die INSERT ... ON DUPLICATE KEY UPDATE-Syntax benutzt, ist das besonders einfach.
MfG ChrisB
Hallo,
danke für den Tipp. Ich glaube das sollte sich so realisieren lassen.
Markus
Hallo,
ich habe nochmals darüber nachgedacht. Wenn ich es so mache, könnte ich ja nur die Klicks eines Tages speichern und nie eine Statistik erstellen, denn wie kann ich wissen, wieviele Klicks am Datum XY gespeichert waren? Entweder ich lösche "klicks" nach jeden Tag, oder ich zähle immer weiter. In beiden Fällen führt es nicht zum gewünschten Ergebnis.
Markus
Nachtrag:
Ich glaube ich habe mich da jetzt nur selbst verwirrt. Die Lösung ist schon gut so. :)
Hallo,
du möchtest direkt in eine Fakt-Tabelle eines Star-Schemas Records einfügen. Der Klick wäre dann der Fakt selbst und besteht somit nur aus einer kombination der Dimension(swerte)? Wenn du dazu eine bestehende Tabelle für die Zeitdimension führen willst, hast du in der Tat ein paar kleines Probleme -> du müsstest sie vor-füllen. Sowas machst du aber insgesamt nur einmal und nicht jedes mal.
Wie hoch bzw. fein soll denn die Granularität der Zeitdimension sein. Tagweise, wie du bereits erwähnt hast? Dann könnte der PK dieser Tabelle einfach eine numerisch-serialisierte Variante des Datums sein. Bei MS SQL Server ergibt ein CONVERT(int, '1900-01-02') eine 1. Bei einem Insert könnte man so implizit einen korrekten Fremdschlüsselwert erhalten, ohne erst ein Lookup auf die Dimensionstabelle machen zu müssen.
Die Ausgestaltung der Dimensionstabelle mit persistierten Werten für "Label", Wochentag, Wochennummer, Monat, Jahr, Quartal usw. für die Zeit ist dann deiner Phantasie überlassen. Implizit lassen sich dann auch Dimensionshierarchien schnell aufbauen.
In meinem Data Warehouse :) ist die Grösse der Tabelle für die Dimension "Zeit" absolut unsignifikant (7500kb). Es sind da Daten drin von 1980 bis 2099 ...
Befüllen machst du mit einem Script (PHP Script, SQL Batch), welches zum Beispiel eine Schleife von x bis y hat und für jeden Schleifendurchlauf ein Insert in die Zeittabelle macht. Da sowas nur einmal alle paar zig Jahre gemacht wird, dürfte es nicht stören, wenn es 5 min dauert.
Eine ganz andere Alternative ohne explizite Tabelle für die Dimension Zeit wäre: Du speicherst das Klickdatum direkt als Datums-Datentyp in die Fakttabelle. Wannimmer du dann Auswertungen machst, benutzt du Datumsfunktionen und Aggregatsfunktionen. Indizieren dieser Datumsspalte sollte da die Performance verbessern.
Hoffe dir etwas geholfen zu haben.
Cheers, Frank
Hallo
du möchtest direkt in eine Fakt-Tabelle eines Star-Schemas Records einfügen. Der Klick wäre dann der Fakt selbst und besteht somit nur aus einer kombination der Dimension(swerte)? Wenn du dazu eine bestehende Tabelle für die Zeitdimension führen willst, hast du in der Tat ein paar kleines Probleme -> du müsstest sie vor-füllen. Sowas machst du aber insgesamt nur einmal und nicht jedes mal.
Wie hoch bzw. fein soll denn die Granularität der Zeitdimension sein. Tagweise, wie du bereits erwähnt hast? Dann könnte der PK dieser Tabelle einfach eine numerisch-serialisierte Variante des Datums sein. Bei MS SQL Server ergibt ein CONVERT(int, '1900-01-02') eine 1. Bei einem Insert könnte man so implizit einen korrekten Fremdschlüsselwert erhalten, ohne erst ein Lookup auf die Dimensionstabelle machen zu müssen.
Diese Problematik war mir bereits ein Dorn im Auge, denn bei jedem Klick ein Lookup wäre sehr unperformant. Aber das mit dem Hash-Wert ist ein guter Ansatz. Habe ich bei MySQL eine ähnliche Möglichkeit, bzw wie könnte ich das hier am besten lösen. Notfalls auch programmatisch.
Markus
Hi,
Diese Problematik war mir bereits ein Dorn im Auge, denn bei jedem Klick ein Lookup wäre sehr unperformant. Aber das mit dem Hash-Wert ist ein guter Ansatz. Habe ich bei MySQL eine ähnliche Möglichkeit, bzw wie könnte ich das hier am besten lösen.
Wie wäre es bspw. damit?
TO_DAYS(date) - Given a date date, returns a day number (the number of days since year 0).
MfG ChrisB