File QVD - apa yang ada di dalamnya, bagian 2

Dalam artikel pertama tentang struktur file QVD, saya menggambarkan struktur umum dan memikirkan metadata dengan cukup detail. Pada artikel ini, saya akan menjelaskan format untuk menyimpan informasi tentang kolom, dan berbagi pengalaman saya dalam menafsirkan data ini.


Jadi (ingat) file QVD sesuai dengan tabel relasional, yang, seperti yang Anda ketahui, terdiri dari baris. Setiap baris tabel, pada gilirannya, terdiri dari kolom (atau bidang), dan baris memiliki struktur yang sama, yang dapat dijelaskan, misalnya oleh operator SQL (buat tabel).


Dalam file QVD, sebuah tabel disimpan sebagai dua bagian yang tidak langsung terkait:


Tabel karakter (istilah saya) mengandung nilai unik untuk setiap kolom di tabel sumber. Ini tentang mereka yang akan kita bahas di bawah ini.


Tabel baris berisi baris tabel sumber, setiap baris menyimpan indeks nilai kolom (bidang) dari baris dalam tabel simbol yang sesuai. Saya akan membahas tabel baris secara lebih rinci di bagian ketiga dari seri ini.


Pada contoh piring kami (ingat - dari bagian pertama)


SET NULLINTERPRET =<sym>; tab1: LOAD * INLINE [ ID, NAME 123.12,"Pete" 124,12/31/2018 -2,"Vasya" 1,"John" <sym>,"None" ]; 

Di piring ini:


  • 5 baris
  • bidang "ID" memiliki 4 nilai unik (NULL tidak dianggap sebagai nilai, lebih detail tentangnya di bagian ketiga)
  • bidang β€œNAME” memiliki 5 nilai unik
  • baris pertama dalam tabel baris akan berisi indeks 0 dan 0, masing-masing sesuai dengan nilai 123,12 dan "Pete"

Acara khusus


Sebagai aturan, tabel simbol dibuat untuk semua bidang tabel dalam file QVD. Namun ada nuansa.


Jika bidang memiliki satu nilai, maka nilai ini biasanya disimpan dalam tabel simbol (dalam hal ini, tabel simbol akan berisi satu catatan). Dan dalam tabel baris, bidang tidak akan ada (karena jelas nilai bidang ini di setiap baris ...)


Jika bidang tidak memiliki nilai sama sekali (selalu berisi NULL), tidak ada tabel simbol yang dibuat di sana.


Kasus khusus ini akan dijelaskan di bagian ketiga, ketika kita sampai pada garis dan algoritma untuk rekreasi mereka.


Menyimpan tabel karakter dalam file


Setiap tabel simbol disimpan dalam file QVD sebagai blok biner, offsetnya (relatif terhadap awal blok biner) terkandung dalam bidang Offset bagian metadata dari bidang ini, panjangnya (dalam byte) adalah di bidang Panjang metadata.


Dengan demikian, tabel karakter pertama akan selalu memiliki offset 0.


Tabel simbol mengikuti satu demi satu dan tidak dipisahkan satu sama lain dengan cara apa pun.


Struktur Tabel Karakter


Tabel simbol berisi nilai-nilai bidang yang saling mengikuti tanpa pemisah, setiap nilai diwakili sebagai berikut:


  • satu byte mengkodekan tipe bidang (saya akan jelaskan di bawah)
  • kemudian muncul nilai biner opsional (tergantung pada jenis bidang)
  • diikuti oleh nilai string opsional (tergantung pada jenis bidang)

String disimpan "sebagaimana adanya" (dalam pengkodean yang ditentukan dalam metadata), string berakhir dengan byte nol. String dapat memiliki panjang nol, mis. hanya terdiri dari nol byte.


Nilai biner disimpan sesuai dengan aturan arsitektur tempat file QVD dihasilkan (dari pengalaman saya, Anda bisa membacanya sebagai nilai biner dengan mata "endian").


Jenis bidang


Seluruh variasi tipe data QVD disatukan dengan tiga dasar


  • (1) integer (4 byte)
  • (2) titik apung (8 byte)
  • (4) baris yang diakhiri dengan nol

Ada juga tipe gabungan


  • (5) integer diikuti oleh representasi stringnya (4 byte plus string dengan byte nol)
  • (6) angka floating-point diikuti oleh representasi string-nya (8 byte plus string dengan byte nol)

Dalam tanda kurung saya telah memberikan nilai numerik dari "jenis" (byte pertama dari nilai bidang dalam tabel simbol).


Pikiran yang bertanya akan bertanya, "di mana ketiganya?" Ini bukan untuk saya, saya juga punya banyak pertanyaan, dari komentar di sini, seperti kata pahlawan Khabensky dalam film terkenal "Aku akan menahan diri ...".


Secara umum, itu saja, tidak sulit - kan?


Dua pengamatan praktis yang tidak terlalu menyenangkan


Satu dan bidang yang sama dapat memiliki nilai tipe yang berbeda di tabel simbol (integer, mengambang, dan string). Saya sendiri tidak percaya sampai saya melakukan serangkaian percobaan ... Satu-satunya hal yang dapat "dijamin" (dengan peringatan dari bagian pertama - tidak ada yang bisa dijamin) - tidak ada campuran "angka" dan "angka dengan string" (baik satu atau yang lain) ) Ini penting, pikiran yang bertanya akan mengerti :-).


Nilai-nilai bidang non-numerik (bukan tipe 1 dan 2 dalam notasi di atas) harus dibaca berturut-turut - tidak mungkin untuk memposisikan diri pada nomor bidang N ... Dapat dimengerti, tetapi tidak efisien (dalam hal pemrosesan).


Perhatikan lagi label kami di atas, tabel karakter bidang ID akan terlihat seperti ini (saya menulis byte / karakter):


  • angka 6 (tipe) + 8 byte (nilai mengambang 123,12) + 7 byte (string "123,12" dengan nol byte)
  • angka 5 (tipe) + 4 byte (nilai integer 124) + 4 byte (string "124" dengan byte nol)
  • angka 5 (tipe) + 4 byte (integer -2) + 3 byte (string "-2" dengan nol byte)
  • angka 5 (tipe) + 4 byte (integer 1) + 2 byte (string "1" dengan byte nol)

Total 40 byte (lihat bagian sebelumnya - metadata, nilai atribut Length untuk bidang ID).


Dari latihan


Tugas praktis (salah satunya), seperti yang sudah saya tulis, bagi saya adalah membuat ulang tabel menggunakan file QVD. Dari uraian di atas berikut (setidaknya - harus mengikuti, saya mencoba :-)) bahwa dari uraian kolom (metadata plus data) tidak mungkin menentukan jenis bidang secara jelas (yang, misalnya, tulis dalam "buat tabel ...") .


Seperti yang saya sebutkan di bagian pertama - 90% bidang memiliki tipe UNKNOWN dalam metadata, tag juga tidak memungkinkan Anda untuk secara unik mengatur jenis bidang (Saya tidak akan memuat pembaca dengan detail - percayalah) ...


Bagaimana menjadi


Dalam pekerjaan saya, saya mengikuti jalur statistik - saya menganalisis persentase tertentu dari nilai kolom dan, berdasarkan hasil, menarik kesimpulan - jenis apa yang akan ditugaskan padanya. Keakuratannya cukup memuaskan, masalahnya adalah Anda perlu menganalisis (dalam kasus umum) semua data ... Dalam praktik saya, saya membatasi diri pada 5-10% pertama dari nilai bidang.


Jika kita berakhir dengan tentang tipe data, maka pikiran yang bertanya akan mengajukan pertanyaan yang masuk akal - "buat tabel" yang disebutkan menyiratkan lebih banyak tipe data ...


Saya akan mengatakan ini: dalam file yang diproses tidak ditemukan tipe data selain yang tercantum di atas. File-file tersebut berhubungan dengan tabel nyata dari database nyata dan berisi seluruh spektrum tipe data (misalnya, saya bahkan mendapat gumpalan ... Mengapa mereka berada di QVD ??? Akan lebih baik untuk menulis komentar).


Mungkin, untuk melengkapi gambar dengan tipe data, Anda perlu menjelaskan tentang tanggal dan stempel waktu (tipe lain adalah masalah panjang).


Tanggal disajikan dalam QVD sebagai bilangan bulat - jumlah hari dari awal era (era klik). Pakar QlikView / QlikSense akan dengan mudah memberi tahu Anda saat dimulai (meskipun 30 Desember 1899, jangan tanya kenapa).


Stempel waktu di QVD diwakili oleh angka floating-point yang berisi tanggal seperti yang dijelaskan di atas, dan waktu di bagian fraksional (di mana 0,0 sesuai dengan waktu "00:00:00" dan 0,999999 sesuai dengan waktu "23:59:59" - lihat lebih detail, misalnya di sini ).


Saya belum menggali jauh ke arah ini - tabel saya yang dibuat ulang dari QVD berisi tipe bilangan bulat dan mengambang untuk bidang seperti "tanggal" dan "datetime". Atau, Anda bisa menggunakan representasi string - untuk bidang tipe ini representasi gabungan selalu digunakan (tipe 5 dan 6).


Yang terakhir (tentang latihan) - saat membaca file besar, adalah logis untuk membuat indeks untuk bidang string, yang saya lakukan. Ini secara signifikan mengurangi waktu pemrosesan dalam kasus di mana ukuran tabel simbol jauh lebih sedikit daripada jumlah baris (mis., Satu nilai terjadi lebih dari satu kali di bidang tabel asli).


Untuk meringkas


Dalam artikel ini, kami memeriksa penyimpanan nilai unik bidang (kolom), melihat bahwa kolom disimpan sebagai urutan nilai unik, menyadari bahwa tipe data dicampur dan hanya ada tiga jenis (integer, mengambang, dan baris).


Selanjutnya, kita perlu berkenalan dengan bagaimana string disimpan - bagian ketiga dan terakhir dari serangkaian artikel tentang struktur QVD akan dikhususkan untuk ini.

Source: https://habr.com/ru/post/id455940/


All Articles