Saya berpikir untuk menggunakan model entitas-atribut-nilai (EAV) untuk beberapa hal di salah satu proyek, tetapi semua pertanyaan tentang hal itu di Stack Overflow berakhir dengan jawaban yang menyebut EAV sebagai anti-pola.
Tapi saya bertanya-tanya apakah itu salah dalam semua kasus.
Katakanlah entitas produk toko, ia memiliki fitur umum, seperti nama, deskripsi, gambar, dan harga, yang mengambil bagian dalam banyak tempat logika dan memiliki (semi) fitur unik, seperti arloji dan bola pantai akan dijelaskan oleh aspek yang sama sekali berbeda. Jadi saya pikir EAV akan cocok untuk menyimpan fitur-fitur unik (semi).
Semua ini dengan asumsi, bahwa untuk menampilkan daftar produk, cukup info di tabel produk (itu berarti tidak ada EAV yang terlibat) dan tepat ketika menunjukkan satu produk / membandingkan hingga 5 produk / dll. data yang disimpan menggunakan EAV digunakan.
Saya telah melihat pendekatan semacam itu dalam perdagangan Magento dan ini cukup populer, jadi apakah ada kasus ketika EAV masuk akal?
Jawaban:
https://web.archive.org/web/20140831134758/http://www.dbforums.com/database-concepts-design/1619660-otlt-eav-design-why-do-people-hate.html
EAV memberikan fleksibilitas kepada pengembang untuk menentukan skema yang diperlukan dan ini bagus dalam beberapa keadaan.
Di sisi lain, kinerjanya sangat buruk dalam hal kueri yang tidak jelas dan dapat mendukung praktik buruk lainnya.
Dengan kata lain, EAV memberi Anda cukup banyak tali untuk menggantung diri dan dalam industri ini, segala sesuatunya harus dirancang dengan tingkat kerumitan terendah karena orang yang menggantikan Anda dalam proyek itu kemungkinan besar akan menjadi idiot.
sumber
Singkatnya, EAV berguna ketika daftar atribut Anda sering bertambah, atau ketika itu sangat besar sehingga sebagian besar baris akan diisi dengan sebagian besar NULL jika Anda membuat setiap atribut menjadi kolom. Ini menjadi anti-pola ketika digunakan di luar konteks itu.
sumber
CREATE TABLE
untuk atribut baru?Menggunakan struktur EAV untuk memiliki beberapa implikasi yang merupakan trade off.
Anda memperdagangkan 'ruang lebih sedikit untuk baris karena Anda tidak memiliki 100 kolom yang
null
' menentang 'kueri dan model yang lebih rumit'.Memiliki EAV biasanya berarti nilainya adalah string tempat seseorang dapat memasukkan data apa pun. Ini kemudian memiliki implikasi pada validitas dan pengecekan kendala. Pertimbangkan situasi di mana Anda telah menempatkan jumlah baterai yang digunakan sebagai sesuatu di tabel EAV. Anda ingin menemukan senter yang menggunakan baterai berukuran C, tetapi kurang dari 4 di antaranya.
Hal yang perlu disadari di sini adalah Anda tidak dapat menggunakan indeks secara wajar pada nilainya. Anda juga tidak dapat mencegah seseorang memasukkan sesuatu yang bukan bilangan bulat di sana, atau bilangan bulat tidak valid (menggunakan baterai '-1') karena kolom nilai digunakan berulang kali untuk tujuan yang berbeda.
Ini kemudian memiliki implikasi dalam mencoba menulis model untuk produk tersebut. Anda akan memiliki nilai yang diketik dengan baik ... tetapi Anda juga akan memiliki
Map<String,String>
hanya duduk di sana dengan segala macam barang di dalamnya. Hal ini kemudian memiliki implikasi lebih lanjut ketika serialisasi itu ke XML atau JSON dan kompleksitas mencoba untuk melakukan validasi atau query terhadap orang-orang struktur.Beberapa alternatif atau modifikasi pada pola untuk dipertimbangkan adalah bukan kunci bentuk bebas, untuk memiliki tabel lain dengan kunci yang valid. Itu berarti alih-alih melakukan perbandingan string dalam database, Anda memeriksa terhadap kesetaraan id kunci asing. Mengubah kunci itu sendiri dilakukan di satu tempat. Anda memiliki seperangkat kunci yang dikenal yang berarti bahwa mereka dapat dilakukan sebagai enum.
Anda juga bisa memiliki tabel terkait yang berisi atribut dari kelas produk tertentu. Sebuah departemen kelontong dapat memiliki meja lain yang memiliki beberapa atribut yang terkait dengannya bahwa bahan bangunan tidak perlu (dan sebaliknya).
Ada saat-saat yang terutama panggilan untuk meja EAV.
Pertimbangkan situasi di mana Anda tidak hanya menulis sistem inventaris untuk perusahaan Anda di mana Anda mengetahui setiap produk dan setiap atribut. Anda sekarang sedang menulis sistem persediaan untuk dijual ke perusahaan lain. Anda tidak dapat mengetahui setiap atribut dari setiap produk - mereka harus mendefinisikannya.
Satu ide yang keluar adalah "kami akan membiarkan pelanggan memodifikasi tabel" dan ini hanya buruk (Anda masuk ke meta-pemrograman untuk struktur tabel karena Anda tidak lagi tahu di mana, mereka secara meriah dapat merusak struktur atau merusak aplikasi, mereka punya akses untuk melakukan hal-hal yang salah dan implikasi dari akses itu menjadi signifikan). Ada lebih banyak tentang jalur ini di MVC4: Bagaimana cara membuat model saat dijalankan?
Sebagai gantinya, Anda membuat antarmuka administratif ke tabel EAV dan mengizinkannya digunakan. Jika pelanggan ingin membuat entri untuk 'polkadots', ia masuk ke tabel EAV dan Anda sudah tahu cara menghadapinya.
Contohnya dapat dilihat dalam model database untuk Redmine Anda dapat melihat tabel custom_fields, dan tabel custom_values - itu adalah bagian dari EAV yang memungkinkan sistem diperluas.
Perhatikan bahwa jika Anda menemukan seluruh struktur tabel Anda terlihat seperti EAV daripada relasional, Anda mungkin ingin melihat rasa KV dari NoSQL (cassandra, redis, Mongo, ... ...). Sadarilah bahwa ini sering kali disertai pengorbanan lain dalam desain mereka yang mungkin cocok atau tidak sesuai dengan apa yang Anda gunakan. Namun, mereka dirancang khusus dengan maksud struktur EAV.
Anda mungkin ingin membaca SQL vs NoSQL untuk sistem manajemen inventaris
Mengikuti pendekatan ini dengan basis data NoSQL yang berorientasi pada dokumen (sofa, mongo), Anda dapat mempertimbangkan setiap item inventaris sebagai dokumen pada disk ... menarik semuanya dalam satu dokumen dengan cepat. Selanjutnya, dokumen ini disusun sehingga Anda dapat menarik satu hal dengan cepat. Di sisi lain, mencari semua dokumen untuk hal-hal yang cocok dengan atribut tertentu dapat memiliki kinerja yang lebih sedikit (bandingkan dengan menggunakan 'grep' terhadap semua file) ... semuanya merupakan trade off.
Pendekatan lain adalah LDAP di mana seseorang akan memiliki basis dengan semua item yang terkait, tetapi kemudian juga akan memiliki kelas objek tambahan yang diterapkan padanya untuk jenis item lainnya. (lihat Inventarisasi Sistem Menggunakan LDAP )
Setelah Anda menyusuri jalan ini, Anda mungkin menemukan sesuatu yang sama persis dengan apa yang Anda cari ... meskipun semuanya memiliki beberapa pengorbanan.
sumber
6 tahun kemudian
Sekarang JSON di Postgres ada di sini, kami memiliki opsi lain, bagi mereka yang menggunakan Postgres. Jika Anda hanya ingin melampirkan beberapa data tambahan ke suatu produk, maka kebutuhan Anda cukup sederhana. Contoh:
Berikut ini adalah pengantar JSON yang lebih lancar di Postgres: https://www.compose.com/articles/is-postgresql-your-next-json-database/ .
Perhatikan bahwa Postgres sebenarnya menyimpan JSONB, bukan JSON teks biasa, dan ia mendukung indeks pada bidang-bidang di dalam dokumen / bidang JSONB, jika Anda menemukan bahwa Anda sebenarnya ingin melakukan kueri terhadap data tersebut.
Juga, perhatikan bahwa bidang dalam bidang JSONB tidak dapat dimodifikasi secara individual dengan kueri UPDATE; Anda harus mengganti seluruh konten bidang JSONB.
Jawaban ini mungkin tidak secara langsung menjawab pertanyaan, tetapi menawarkan alternatif untuk pola EAV, yang harus dipertimbangkan oleh siapa saja yang merenungkan pertanyaan awal.
sumber
jsonb_set()
fungsi di Postgres 9.5 dan yang lebih baru untuk hal ini. (Artikel yang Anda tautkan ke tautan pada gilirannya ke artikel yang lebih baru membahas penambahan fitur 9.5 .)Biasanya orang melihat ke arah lain jika Anda menggunakannya untuk tabel pencarian, atau situasi lain di mana manfaatnya adalah tetap harus membuat tabel untuk satu atau dua nilai yang disimpan. Situasi yang Anda gambarkan, di mana Anda pada dasarnya menyimpan properti item, terdengar sangat normal (dan dinormalisasi). Memperluas tabel untuk menyimpan sejumlah variabel atribut item adalah ide yang buruk.
Untuk kasus umum menyimpan data yang berbeda dalam tabel tipis yang panjang ... Anda tidak perlu takut untuk membuat tabel baru jika Anda perlu, dan memiliki hanya satu atau dua tabel kurus panjang tidak jauh lebih baik daripada hanya memiliki satu atau dua meja pendek gemuk.
Yang sedang berkata, saya terkenal karena menggunakan tabel EAV untuk logging. Mereka memang memiliki beberapa utilitas yang baik.
sumber
EAV mengubah masalah struktur eksplisit, menjadi persepsi tersirat. Daripada mengatakan X adalah tabel dengan kolom A dan B. Anda menyiratkan bahwa kolom A dan B membentuk tabel X. Itu kebalikannya dalam satu hal tetapi tidak ada pemetaan satu-ke-satu, tentu saja. Anda bisa mengatakan bahwa A dan B memetakan ke tabel (atau ketik) X dan Y. Ini bisa menjadi penting dalam domain yang lebih terlibat di mana konteks penting.
Saya telah mempelajari Datomic, untuk jenis pendekatan ini dan saya pikir ini adalah sistem yang sangat berguna dan kuat dengan batasan pada apa yang harus Anda lakukan dengannya (bukan berarti Anda tidak bisa).
Bahwa EAV akan lambat, atau "memberi Anda cukup tali untuk menggantung diri" bukanlah pernyataan yang akan saya setujui. Sebaliknya, saya akan lebih menekankan pada kekuatan EAV dan jika itu sesuai dengan ruang masalah Anda, Anda harus mempertimbangkannya.
Pengalaman saya adalah bahwa itu adalah pendekatan pemodelan yang indah dan hampir tak terbatas . Khususnya, dalam kasus Datomic, mereka mengenakan set semantik di atas segalanya. Setiap keputusan pemodelan yang memodelkan suatu hubungan dapat dengan bebas beralih dari satu, ke banyak tanpa harus mendesain ulang kolom / tabel. Anda juga dapat kembali selama kendala tidak melanggar invarian. Semuanya sama di bawah tenda.
Masalah dengan EAV ada di pikiran saya adalah kurangnya implementasi seperti Datomic. Karena ini adalah pertanyaan tentang EAV saya tidak ingin membicarakan tentang Datomic tetapi itu adalah salah satu hal di mana saya pikir mereka mendapatkan segalanya dengan benar sehubungan dengan EAV.
sumber