Im ersten Artikel über die Struktur der QVD-Datei habe ich die allgemeine Struktur beschrieben und mich ausreichend mit Metadaten befasst. In diesem Artikel werde ich das Format zum Speichern von Informationen zu Spalten beschreiben und meine Erfahrungen bei der Interpretation dieser Daten teilen.
Denken Sie also daran, dass eine QVD-Datei einer relationalen Tabelle entspricht, die, wie Sie wissen, aus Zeilen besteht. Jede Zeile der Tabelle besteht wiederum aus Spalten (oder Feldern), und die Zeilen haben dieselbe Struktur, die beispielsweise vom SQL-Operator (Tabelle erstellen) beschrieben werden kann.
In einer QVD-Datei wird eine Tabelle als zwei indirekt verwandte Teile gespeichert:
Zeichentabellen (mein Begriff) enthalten eindeutige Werte für jede Spalte in der Quelltabelle. Es geht um sie, die wir unten diskutieren werden.
Die Zeilentabelle enthält Zeilen der Quelltabelle, jede Zeile speichert die Indizes der Spalten- (Feld-) Werte der Zeile in der entsprechenden Symboltabelle. Ich werde die Zeilentabelle im dritten Teil dieser Reihe genauer besprechen.
Am Beispiel unserer Platte (denken Sie daran - aus dem ersten Teil)
SET NULLINTERPRET =<sym>; tab1: LOAD * INLINE [ ID, NAME 123.12,"Pete" 124,12/31/2018 -2,"Vasya" 1,"John" <sym>,"None" ];
In dieser Platte:
- 5 Zeilen
- Das Feld „ID“ enthält 4 eindeutige Werte (NULL wird nicht als Wert betrachtet, ausführlicher im dritten Teil).
- Feld "NAME" hat 5 eindeutige Werte
- Die erste Zeile in der Zeilentabelle enthält die Indizes 0 und 0, die den Werten 123,12 bzw. „Pete“ entsprechen
Besondere Anlässe
In der Regel werden Symboltabellen für alle Tabellenfelder in der QVD-Datei erstellt. Aber es gibt Nuancen.
Wenn das Feld einen Wert hat, wird dieser Wert normalerweise in der Symboltabelle gespeichert (in diesem Fall enthält die Symboltabelle einen Datensatz). Und in der Zeilentabelle fehlt das Feld (damit klar ist, welchen Wert dieses Feld in jeder Zeile haben soll ...)
Wenn das Feld überhaupt keine Werte hat (enthält immer NULL), wird keine Symboltabelle darauf erstellt.
Diese Sonderfälle werden im dritten Teil beschrieben, wenn wir zu den Linien und dem Algorithmus für ihre Neuerstellung kommen.
Speichern von Zeichentabellen in einer Datei
Jede Symboltabelle wird in einer QVD-Datei als Binärblock gespeichert. Ihr Versatz (relativ zum Anfang des Binärblocks) ist im Feld Versatz des Metadatenabschnitts dieses Felds enthalten. Die Länge (in Byte) befindet sich im Feld Länge der Metadaten.
Somit hat die erste Zeichentabelle immer einen Versatz von 0.
Die Symboltabellen folgen nacheinander und sind in keiner Weise voneinander getrennt.
Zeichentabellenstruktur
Die Symboltabelle enthält Feldwerte, die ohne Trennzeichen aufeinander folgen. Jeder Wert wird wie folgt dargestellt:
- Ein Byte codiert den Feldtyp (ich werde unten beschreiben)
- dann kommt der optionale Binärwert (abhängig von der Art des Feldes)
- gefolgt von einem optionalen Zeichenfolgenwert (abhängig vom Feldtyp)
Zeichenfolgen werden "wie sie sind" gespeichert (in der in den Metadaten angegebenen Codierung). Die Zeichenfolge endet mit einem Null-Byte. Die Zeichenfolge kann eine Länge von Null haben, d.h. bestehen nur aus Null Byte.
Binärwerte werden gemäß den Regeln der Architektur gespeichert, in der die QVD-Datei generiert wurde (meiner Erfahrung nach können Sie sie einfach als Binärwerte mit Blick auf "Endian" lesen).
Feldtypen
Die ganze Vielfalt der Datentypen QVD zusammen mit drei grundlegenden
- (1) Ganzzahl (4 Bytes)
- (2) Gleitkomma (8 Bytes)
- (4) Zeile endet mit Null
Es gibt auch kombinierte Typen
- (5) eine Ganzzahl, gefolgt von ihrer Zeichenfolgendarstellung (4 Bytes plus eine Zeichenfolge mit einem Nullbyte)
- (6) eine Gleitkommazahl gefolgt von ihrer Zeichenfolgendarstellung (8 Bytes plus eine Zeichenfolge mit einem Nullbyte)
In Klammern habe ich die numerischen Werte der "Typen" angegeben (das erste Byte des Feldwerts in der Symboltabelle).
Ein fragender Geist wird fragen: "Wo sind die drei?" Das ist nichts für mich, ich habe auch viele Fragen aus den Kommentaren hier, wie der Held von Chabenski in dem berühmten Film "Ich werde es unterlassen ..." sagte.
Im Allgemeinen ist das alles, es ist nicht schwierig - richtig?
Zwei nicht sehr angenehme praktische Beobachtungen
Ein und dasselbe Feld kann Werte unterschiedlichen Typs in der Symboltabelle enthalten (Ganzzahl, Gleitkomma und Zeichenfolgen). Ich selbst habe es nicht geglaubt, bis ich eine Reihe von Experimenten durchgeführt habe ... Das einzige, was "garantiert" werden kann (mit dem Vorbehalt aus dem ersten Teil - nichts kann garantiert werden) - es kann keine Mischung aus "Zahl" und "Zahl mit einer Zeichenfolge" geben (entweder die eine oder die andere) ) Das ist wichtig, ein forschender Verstand wird verstehen :-).
Die Werte nicht numerischer Felder (nicht die Typen 1 und 2 in der obigen Notation) müssen in einer Reihe gelesen werden - es ist unmöglich, sich auf Feldnummer N zu positionieren ... Es ist verständlich, aber ineffizient (in Bezug auf die Verarbeitung).
Betrachten Sie noch einmal unsere Bezeichnung oben, die Zeichentabelle des ID-Felds sieht folgendermaßen aus (ich schreibe Byte / Zeichen):
- Nummer 6 (Typ) + 8 Bytes (Gleitkommawert 123,12) + 7 Bytes (Zeichenfolge "123,12" mit Null Byte)
- Nummer 5 (Typ) + 4 Bytes (ganzzahliger Wert 124) + 4 Bytes (Zeichenfolge "124" mit Null Byte)
- Nummer 5 (Typ) + 4 Bytes (Ganzzahl -2) + 3 Bytes (Zeichenfolge "-2" mit Null Byte)
- Nummer 5 (Typ) + 4 Bytes (Ganzzahl 1) + 2 Bytes (Zeichenfolge "1" mit Null Byte)
Insgesamt 40 Bytes (siehe vorherigen Teil - Metadaten, der Wert des Längenattributs für das ID-Feld).
Aus der Praxis
Die praktische Aufgabe (eine von) bestand für mich, wie ich bereits schrieb, darin, die Tabelle mithilfe der QVD-Datei neu zu erstellen. Aus dem Obigen folgt (zumindest - es sollte folgen, ich habe versucht :-)), dass es aus der Beschreibung der Spalte (Metadaten plus Daten) unmöglich ist, den Feldtyp eindeutig zu bestimmen (einen, der beispielsweise in die "Tabelle erstellen ..." schreibt). .
Wie ich im ersten Teil erwähnt habe - 90% der Felder haben einen UNBEKANNTEN Typ in den Metadaten. Mit den Tags können Sie den Feldtyp auch nicht eindeutig festlegen (ich werde den Reader nicht mit den Details laden - glauben Sie mir) ...
Wie man ist
In meiner Arbeit bin ich den statistischen Weg gegangen - ich analysiere einen bestimmten Prozentsatz der Spaltenwerte und ziehe aus den Ergebnissen eine Schlussfolgerung - welchen Typ ich ihm zuweisen soll. Die Genauigkeit ist ziemlich zufriedenstellend, das Problem ist, dass Sie (im allgemeinen Fall) alle Daten analysieren müssen ... In meiner Praxis habe ich mich auf die ersten 5-10% der Feldwerte beschränkt.
Wenn wir mit Datentypen enden, wird ein fragender Verstand eine vernünftige Frage stellen - die erwähnte "Tabelle erstellen" impliziert viel mehr Datentypen ...
Ich werde dies sagen: In den verarbeiteten Dateien wurden keine anderen Datentypen als die oben aufgeführten gefunden. Die Dateien entsprachen sehr realen Tabellen realer Datenbanken und enthielten das gesamte Spektrum der Datentypen (zum Beispiel bekam ich sogar Blobs ... Warum sind sie in QVD ??? Es wäre besser, Kommentare zu schreiben).
Um das Bild mit Datentypen zu vervollständigen, müssen Sie wahrscheinlich Datums- und Zeitstempel erläutern (andere Typen sind eine Frage der Länge).
Daten werden in QVD als Ganzzahl dargestellt - die Anzahl der Tage ab dem Beginn der Ära (Klick-Ära). QlikView / QlikSense-Experten werden Ihnen leicht sagen, wann es begonnen hat (obwohl es der 30. Dezember 1899 war, fragen Sie nicht warum).
Zeitstempel in QVD werden durch eine Gleitkommazahl dargestellt, die das oben beschriebene Datum und die Uhrzeit im Bruchteil enthält (wobei .0 der Zeit "00:00:00" und .999999 der Zeit "23:59:59" entspricht - siehe detaillierter zum Beispiel hier ).
Ich habe noch nicht tief in diese Richtung gegraben - meine aus QVD neu erstellten Tabellen enthalten ganzzahlige und schwebende Typen für Felder wie "Datum" und "Datum / Uhrzeit". Alternativ können Sie die Zeichenfolgendarstellung verwenden - für Felder dieses Typs wird immer eine kombinierte Darstellung verwendet (Typ 5 und 6).
Das letzte (zum Üben) - Beim Lesen großer Dateien ist es logisch, Indizes für Zeichenfolgenfelder zu erstellen, was ich auch getan habe. Dies reduziert die Verarbeitungszeit in Fällen erheblich, in denen die Größe der Symboltabelle viel kleiner als die Anzahl der Zeilen ist (d. H. Ein Wert tritt mehr als einmal im Feld der ursprünglichen Tabelle auf).
Zusammenfassend
In diesem Artikel haben wir die Speicherung eindeutiger Werte von Feldern (Spalten) untersucht, festgestellt, dass Spalten als Folge eindeutiger Werte gespeichert werden, festgestellt, dass die Datentypen gemischt sind und es nur drei Typen gibt (Ganzzahl, Gleitkomma und Zeile).
Als nächstes müssen wir uns mit der Speicherung der Zeichenfolgen vertraut machen - der dritte und letzte Teil einer Reihe von Artikeln über die QVD-Struktur wird diesem Thema gewidmet sein.