Saya perlu mendukung bidang dan nilai dinamis di pusat data besar untuk menyimpan log permintaan API, kasus pengguna saya adalah bahwa saya perlu menyimpan semua string permintaan API dan dapat melakukan kueri terhadap mereka di masa mendatang (jadi bukan hanya penyimpanan, jadi saya tidak bisa menggunakan gumpalan untuk mereka)
misalnya http://example.com/?action=test&foo=abc&bar=def...
Saya perlu menyimpan semua field => value
pemetaan, yaitu (action => test), (foo => abc), (bar => def)
, dan karena bidangnya sangat dinamis, satu-satunya solusi yang saya temukan adalah menggunakan Entity-Attribute-Value, namun, orang-orang terus mengatakan itu adalah desain yang sangat buruk.
Jadi, pertimbangkan kasus penggunaan saya di atas, apa alternatif yang cocok untuk EAV?
Skema saya saat ini menggunakan KAV
Tabel
requests
(id, timestamp, uri)
misalnya(1, 149382220, '/')
Tabel
params
(request_id, key, value)
misalnya(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')
Ada saran?
Pembaruan: Kami menjalankan gudang di AWS RedShift
SQL
tidak cukup spesifik. Anda telah diminta dua kali. Saya yang ketiga.hstore
ataujson
tipe data (ataujsonb
jika / ketika mereka "upgrade" ke 9,4).Jawaban:
Saya dapat memikirkan tiga solusi - EAV, XML, dan Sparse Columns. Yang terakhir ini khusus untuk vendor dan mungkin tidak berguna bagi Anda.
Metode apa pun yang Anda pilih, Anda mungkin ingin mempertimbangkan untuk menyimpan data permintaan asli dalam format mentah, dalam tabel atau file datar. Ini akan membuatnya mudah untuk mencoba cara-cara baru menyimpan data, memungkinkan Anda untuk memuat ulang data jika Anda menemukan kesalahan dengan cara Anda mem-parsing permintaan Anda, dan menawarkan peluang untuk mem-parsing permintaan API menggunakan pemrosesan batch atau "data besar" alat jika Anda menemukan bahwa gudang data Anda tidak dapat menangani data secara efisien.
Pertimbangan EAV
EAV / KVS, seperti yang telah Anda jelaskan di atas, kemungkinan merupakan implementasi yang paling mudah.
Sayangnya itu juga akan menjadi sangat mahal - untuk mendapatkan segala jenis pertanyaan efisien pada kunci yang biasa digunakan, Anda perlu memiliki indeks pada kolom kunci, yang bisa menjadi sangat terfragmentasi. Permintaan kunci tertentu akan sangat mahal.
Anda mungkin dapat mengurangi biaya pengindeksan atau pemindaian indeks dengan mendukung toko EAV Anda dengan tampilan terwujud (banyak vendor mendukung ini) untuk menanyakan kunci atau nilai yang Anda pedulikan.
XML
Sebagian besar sistem basis data perusahaan menawarkan penanganan XML yang sangat matang, termasuk validasi, pengindeksan, dan kueri canggih.
Memuat permintaan API ke dalam database karena XML akan menyediakan satu tuple per permintaan, yang secara logis mungkin sedikit lebih cocok untuk Anda daripada memiliki jumlah baris yang tidak diketahui dalam tabel EAV.
Apakah ini efisien akan sangat tergantung pada vendor RDBMS Anda dan implementasi Anda.
Kelemahan terbesar adalah bahwa ini mungkin satu-satunya cara mengelola data yang lebih rumit daripada manipulasi string dari permintaan asli!
Kolom Jarang / tabel tradisional
Mungkin Anda bisa memuat data Anda ke dalam struktur tabel tradisional, dengan satu kolom per kunci.
Fitur SQL Server's Sparse Columns adalah alternatif yang bagus untuk toko EAV. Tabel dengan Kolom Jarang berperilaku sama seperti tabel normal, kecuali bahwa tabel tersebut dapat memiliki hingga 30.000 kolom, dan nilai NULL dalam kolom jarang tidak menggunakan ruang dalam tabel.
Menggabungkannya dengan Indeks yang Difilter (fitur spesifik SQL Server lain) dapat memberikan alternatif yang sangat efisien untuk toko EAV jika Anda sering meminta beberapa kolom dan / atau nilai tertentu.
Menggunakan tabel tradisional dengan vendor lain mungkin layak - IBM mendukung lebih dari 700 kolom per tabel dan Oracle sekitar 1000, dan fitur seperti kompresi atau perlakuan Oracle terhadap trailing nulls dapat berarti bahwa Anda dapat menyimpan data API Anda dengan cukup efisien.
Kelemahan yang jelas dari pendekatan ini adalah bahwa ketika Anda menambahkan kunci baru ke API Anda, Anda harus menyesuaikan skema Anda.
sumber
hstore
ataujson
. Dalam 9,4 mendatangjsonb
akan menjadi rekomendasi saya.EAV bukanlah desain yang buruk, karena itu, EAV hanyalah desain yang membutuhkan pemikiran yang matang dan dapat dipadukan dengan masalah kinerja seiring dengan meningkatnya jumlah data. Mungkin untuk sistem Anda, itu akan bekerja dengan baik.
Ketika saya mendesain sistem untuk menyimpan string kueri, saya tidak tahu sebelumnya bidang apa yang akan saya minati. Saya membuat tabel untuk menyimpan string kueri dalam format biner serial, dan membangun sistem yang memungkinkan saya untuk memecah kueri. merangkai bagian-bagian komponennya begitu saya tahu bagian yang saya minati. Dari sana saya membuat satu set tabel; masing-masing untuk set data yang biasanya terkandung dalam string kueri.
Misalnya, saya akhirnya memiliki tabel untuk data pengarah, satu untuk data permintaan target, dan satu untuk item terkait pengguna seperti permintaan pencarian yang mereka masukkan.
Saya menemukan kemampuan untuk menyimpan seluruh string kueri dalam satu tabel sebagai gumpalan, sambil memberikan kemampuan untuk memisahkan gumpalan itu di masa depan, memenuhi kebutuhan saya dengan sangat baik.
sumber
BLOB
yang digunakan yang berarti Binary Long OBject. Saya lebih suka menggunakanCLOB
(Character Long OBject) atau sesuatu sepertitext
di PostgreSQL, karena kita berbicara tentang karakter dan bukan data biner.