QlikView dan adiknya QlikSense adalah alat BI luar biasa yang cukup populer di negara kita dan di luar negeri. Sangat sering, sistem ini menyimpan hasil "tengah" dari pekerjaan mereka - data yang memvisualisasikan "dasbor" mereka - ke dalam apa yang disebut "file QVD". Seringkali file QVD digunakan sebagai penyimpanan utama dalam proses ETL multi-tahap yang dibangun berdasarkan Qlik. Dan kemudian beberapa (misalnya, saya - saya berurusan dengan rekayasa data di perusahaan) punya pertanyaan - apakah mungkin dan bagaimana menggunakan data ini tanpa QlikView / QlikSense? Atau yang lain - dan apa yang ada di sana dan apakah benar menghitungnya?
QVD adalah format file yang dioptimalkan untuk QlikView / QlikSense (membaca dari menulis informasi oleh aplikasi ini ke file format ini jauh lebih cepat daripada file format lainnya). Struktur file ini tidak berdokumen dan ditutupi dengan "kesuraman kepemilikan", praktis tidak ada aplikasi yang dapat bekerja dengan file tersebut (baca dan bahkan lebih lagi menulis). Dalam seri artikel ini saya akan membagikan pengalaman dan pengetahuan praktis yang saya peroleh: Saya tahu bagaimana QVD bekerja, saya dapat membaca dan menulis secara langsung dan cepat untuk itu.
Siapa yang akan tertarik pada informasi ini: pertama-tama, mereka yang bekerja dengan QlikView / QlikSense, serta mereka yang (seperti saya) ingin menggunakan data yang disimpan dalam file QVD. Dan, tentu saja, untuk semua orang yang ingin tahu.
Segala sesuatu yang ditulis dalam seri ini didasarkan pada pengalaman pribadi saya, yang, tentu saja, bukan "dokumentasi" atau "jaminan" (bahwa file Anda akan persis sama seperti yang saya jelaskan. Atau bahwa itu akan selamanya ) Saya juga tidak dapat menjamin bahwa saya telah menemukan semua kasing - pasti ada file yang akan berisi sesuatu yang tidak saya jelaskan (jika hanya karena saya tidak menemukan opsi seperti itu). Namun, saya harus mencatat bahwa informasi tersebut diperiksa pada sejumlah besar (beberapa ratus) file yang dibuat oleh orang yang berbeda dari sistem yang berbeda menggunakan versi QlikView / QlikSense yang berbeda.
Dan sedikit tentang bagaimana saya melakukannya: Saya mulai dengan yang sederhana - contoh inline kecil yang disimpan di QVD. Selanjutnya - analisis file biner, upaya otak, tes dan kesalahan. Melihat ke depan (saya akan membicarakan hal ini secara lebih rinci di akhir seri), saya dapat membaca dan menulis file QVD berukuran sedang (ratusan gigabyte) dengan cukup efisien. Titik awal perjalanan saya ke dunia QVD adalah GitHub ini, terima kasih banyak kepada penulis (mencoba menghubunginya - tidak menanggapi).
Apa tujuan saya (selain rasa ingin tahu dan keinginan untuk memverifikasi kebenaran data yang bekerja dengan QlikView / QlikSense), saya perlu membaca konten file QVD, yaitu. buat ulang tabel relasional berdasarkan itu. Sebaliknya, unggah data tabel relasional ke QVD sehingga QlikView dapat memuatnya dengan benar.
Bagaimana saya melihat rangkaian artikel ini
- pengantar, struktur file, metadata (artikel ini)
- penyimpanan informasi kolom
- menyimpan informasi, pencapaian, rencana lini
Struktur file
File QVD dibuat oleh skrip QlikView / QlikSense dalam proses memuat data ke dalam memori aplikasi (hasil dari perintah STORE) dan sesuai dengan satu tabel QlikView / QlikSense (relasional). Ini terdiri dari dua bagian
- tekstual (metadata) dan
- biner (kolom dan baris)
Metadata disajikan sebagai XML (contoh akan diberikan di bawah), bagian biner dimulai segera setelah teks dan terdiri dari dua blok
- nilai unik dari semua kolom (tabel sumber)
- baris (tabel sumber) yang merujuk nilai kolom unik

Jadi, untuk tabel N kolom, file tersebut akan berisi N + 1 blok biner. Semua bagian file "direkatkan" dan berjalan satu demi satu tanpa filler dan "shanks".
File QVD berisi banyak metadata - "data tentang data". Ini hampir swasembada, nilai sendiri, berikut adalah daftar singkat apa yang ada dalam metadata (saya akan jelaskan secara lebih rinci di bawah):
- versi perangkat lunak yang menghasilkan file
- tanggal dan waktu pembuatan file
- File QlikView / QlikSense, skrip yang mengarah ke pembuatan file
- kode sumber skrip yang menghasilkan file QVD
- nama tabel
- informasi kolom (nama, jenis, jumlah nilai unik)
- jumlah baris
Metadata disimpan dalam file dalam bentuk teks dan dapat dilihat dalam program apa pun yang dapat menampilkan file dalam bentuk teks (well, hampir semua ... dalam satu yang tidak takut pada file besar). Secara pribadi, saya melihat meta-informasi menggunakan lebih banyak - itu cukup nyaman.
Dalam presentasi berikut, saya akan menggunakan tabel tes (saya menggunakan sintaks QlikView, tapi saya pikir ini akan mudah untuk dikira):
SET NULLINTERPRET =<sym>; tab1: LOAD * INLINE [ ID, NAME 123.12,"Pete" 124,12/31/2018 -2,"Vasya" 1,"John" <sym>,"None" ];
Saya akan memberikan contoh metadata untuk piring ini
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <QvdTableHeader> <QvBuildNo>7314</QvBuildNo> <CreatorDoc></CreatorDoc> <CreateUtcTime>2019-04-03 06:24:33</CreateUtcTime> <SourceCreateUtcTime></SourceCreateUtcTime> <SourceFileUtcTime></SourceFileUtcTime> <SourceFileSize>-1</SourceFileSize> <StaleUtcTime></StaleUtcTime> <TableName>tab1</TableName> <Fields> <QvdFieldHeader> <FieldName>ID</FieldName> <BitOffset>0</BitOffset> <BitWidth>3</BitWidth> <Bias>-2</Bias> <NumberFormat> <Type>0</Type> <nDec>0</nDec> <UseThou>0</UseThou> <Fmt></Fmt> <Dec></Dec> <Thou></Thou> </NumberFormat> <NoOfSymbols>4</NoOfSymbols> <Offset>0</Offset> <Length>40</Length> </QvdFieldHeader> <QvdFieldHeader> <FieldName>NAME</FieldName> <BitOffset>3</BitOffset> <BitWidth>5</BitWidth> <Bias>0</Bias> <NumberFormat> <Type>0</Type> <nDec>0</nDec> <UseThou>0</UseThou> <Fmt></Fmt> <Dec></Dec> <Thou></Thou> </NumberFormat> <NoOfSymbols>5</NoOfSymbols> <Offset>40</Offset> <Length>37</Length> </QvdFieldHeader> </Fields> <Compression></Compression> <RecordByteSize>1</RecordByteSize> <NoOfRecords>5</NoOfRecords> <Offset>77</Offset> <Length>5</Length> </QvdTableHeader>
Pengalaman saya dengan QVD menunjukkan bahwa struktur XML tidak berubah dari file ke file.
Saya akan mengomentari elemen metadata yang paling penting.
QvBuildNo
Nomor build aplikasi QlikView / QlikSense yang menghasilkan file QVD.
Creatordoc
Sebagai aturan, ini berisi nama file QVW, skrip yang menghasilkan file QVD. Contoh ini kosong, mungkin karena Edisi Pribadi digunakan.
BuatUtcTime
Waktu pembuatan file QVD.
SourceCreateUtcTime, SourceFileUtcTime, SourceFileSize, StaleUtcTime
Saya tidak melihat file di mana bidang ini akan diisi - untuk pikiran bertanya: mungkin beberapa pengaturan hilang?
Tablename
Nama tabel di QlikView (lihat contoh di atas).
Ngomong-ngomong, kata-kata "bidang" dan "kolom" adalah sinonim bagi saya, jangan khawatir jika saya menggunakan keduanya (saya akan mencoba untuk tidak melakukan ini, tetapi masih ...).
Informasi tentang setiap bidang disimpan di QVD tentang
Fieldname
Nama bidang (sekali lagi dalam hal QlikView, yaitu, mengingat "AS")
BitOffset, BitWidth, Bias
Untuk sekarang, mari kita lewati - ini adalah informasi untuk "decoding string", kami akan mempertimbangkan di bagian ketiga ketika akan berurusan dengan string.
Ketik, nDec, UseThou, Fmt, Dec, Thou
Dikandung dengan baik (dilihat dari namanya), tetapi sama sekali tidak berguna dari sudut pandang mencapai informasi tujuan saya (untuk lebih jelasnya, lihat bagian kedua, di mana kita akan berbicara tentang kolom). Kenapa itu tidak berguna? - tag "Type" tidak berkorelasi dengan tipe data yang disimpan di bagian biner. Tidak mungkin mengembalikan jenis kolom darinya (tampaknya akan lebih mudah, ada tag Jenis!). Dalam 90% kasus, nilai tag ini akan menjadi string TIDAK DIKENAL ...
Dalam metadata tentang kolom masih ada data seperti itu (dalam metadata contoh itu tidak, tampaknya, karena ukurannya yang kecil)
<Comment></Comment> <Tags> <String>$numeric</String> <String>$integer</String> </Tags>
Komentar tidak membutuhkan komentar (omong-omong, file yang saya kerjakan 100% kosong ...).
Tag juga tidak berguna (dari sudut pandang memulihkan struktur tabel) informasi. Tetapi dari situ Anda dapat menebak kira-kira jenis informasi apa yang disimpan dalam kolom. Saya akan menyentuh mengetik lebih detail di bagian kedua - ketika saya akan berbicara tentang kolom: ini penting. Tetapi sedikit lebih rumit dari yang saya inginkan.
NoOfSymbols
Jumlah entri di bagian biner yang terkait dengan kolom ini. Seperti yang kita lihat, dalam contoh kita adalah 5. Informasi yang sangat penting untuk dekripsi.
Offset
Offset blok data kolom ini dalam byte relatif terhadap awal bagian biner file. Juga sangat penting.
Panjangnya
Panjang seluruh blok data kolom ini dalam byte. Perhatikan bahwa representasi biner dari elemen kolom (sel tabel) umumnya memiliki panjang variabel (baris, misalnya), sehingga panjangnya tidak dapat dihitung, Anda hanya dapat mengambil dari tag ini (tersenyum).
Kompresi
Tidak pernah diisi (dalam data yang saya kerjakan). Mungkin kita tidak menggunakan opsi ini ...
RecordByteSize
Ukuran entri baris dalam byte. Semua string diwakili dalam blok biner string sebagai indeks bit (lebih lanjut tentang ini di bagian ketiga), indeks bit terdiri dari baris dengan panjang yang sama.
NoOfRecords
Jumlah baris (dalam indeks bit dan dalam tabel sumber).
Offset
Offset indeks bit (blok dengan informasi string) dalam byte relatif terhadap awal bagian biner file.
Panjangnya
Panjang indeks bit dalam byte.
Dalam metadata tentang string masih ada data seperti itu (lagi - contoh singkat tidak memungkinkan Anda untuk melihat semuanya, tetapi memungkinkan Anda untuk memahami kompleksnya)
<Lineage> <LineageInfo> <Discriminator>Provider=OraOLEDB.Oracle.1;Persist Security Info=True;Data Source=XXXX;Extended Properties=""</Discriminator> <Statement>LinkTable: LOAD SOURCE_NAME & '_' & SOURCE_ID as SYSKEY, HID_PARTY;SQL SELECT * FROM UNITED_VIEW</Statement> </LineageInfo> <LineageInfo> <Discriminator>Provider=OraOLEDB.Oracle.1;Persist Security Info=True;Data Source=XXXX;Extended Properties=""</Discriminator> <Statement>SQL SELECT * FROM UNITED_VIEW</Statement> </LineageInfo> <LineageInfo> <Discriminator>STORE - \\xxx.ru\mfs\SPECIAL\Qlikview\QVData\LinkTable.qvd (qvd)</Discriminator> <Statement></Statement> </LineageInfo> </Lineage> <Comment></Comment>
Saya tidak akan terlalu mempermasalahkan hal ini, ini cukup bisa dimengerti (SELECT asli yang menghasilkan tabel di QlikView), saya masih belum mengetahuinya (kadang-kadang berlipat ganda) ... (kecuali untuk satu - 100% tidak ada komentar (senyum)) .
Untuk meringkas
- File QVD mandiri (mis. Dapat dianalisis secara terpisah dari data lain)
- File QVD terdiri dari bagian teks (metadata) dan biner (kolom dan indeks bit)
- metadata adalah XML dengan semantik yang jelas
Seorang pembaca yang ingin tahu memiliki hak untuk bertanya di sini: "Sejauh ini tidak ada yang baru telah didengar, semua hal di atas dapat diambil dan dilihat dalam header XML file QVD ... Ini telah ditulis berulang kali tentang ini di Internet yang berbeda, apa yang baru?" Itu benar - bagian pertama hampir seluruhnya dikhususkan untuk metadata. Tapi ini bukan akhirnya.
Apa selanjutnya - di bagian selanjutnya, kita akan memeriksa secara rinci struktur bagian biner dari file QVD yang berisi informasi tentang kolom (nilai unik dari semua kolom tabel).