Database Nilai Atribut Entitas vs. E-niaga Model Relasional yang ketat

136

Dapat dikatakan bahwa model database EAV / CR buruk. Yang mengatakan,

Pertanyaan: Model database, teknik, atau pola apa yang harus digunakan untuk menangani "kelas" atribut yang mendeskripsikan produk e-commerce yang dapat diubah pada waktu proses?

Dalam database E-commerce yang baik, Anda akan menyimpan beberapa kelas opsi (seperti resolusi TV, kemudian memiliki resolusi untuk setiap TV, tetapi produk berikutnya mungkin bukan TV dan tidak memiliki "resolusi TV"). Bagaimana Anda menyimpannya, mencari secara efisien, dan memungkinkan pengguna Anda untuk mengatur jenis produk dengan kolom variabel yang menjelaskan produk mereka? Jika mesin telusur menemukan bahwa pelanggan biasanya menelusuri TV berdasarkan kedalaman konsol, Anda dapat menambahkan kedalaman konsol ke bidang Anda, lalu menambahkan kedalaman tunggal untuk setiap jenis produk TV pada waktu proses.

Ada fitur umum yang bagus di antara aplikasi e-niaga yang bagus di mana mereka menampilkan sekumpulan produk, lalu memiliki menu samping "lihat perincian" di mana Anda dapat melihat "Resolusi TV" sebagai tajuk, dan lima Resolusi TV paling umum untuk set ditemukan. Anda mengklik satu dan itu hanya menampilkan TV dengan resolusi itu, memungkinkan Anda untuk menelusuri lebih lanjut dengan memilih kategori lain di menu samping. Opsi ini akan menjadi atribut produk dinamis yang ditambahkan pada waktu proses.

Diskusi lebih lanjut:

Singkat cerita, apakah ada tautan di Internet atau deskripsi model yang dapat "secara akademis" memperbaiki penyiapan berikut? Saya berterima kasih kepada Noel Kennedy karena menyarankan tabel kategori, tetapi kebutuhannya mungkin lebih besar dari itu. Saya menjelaskannya dengan cara berbeda di bawah ini, mencoba untuk menyoroti signifikansinya. Saya mungkin memerlukan koreksi sudut pandang untuk memecahkan masalah, atau saya mungkin perlu mempelajari lebih dalam tentang EAV / CR.

Suka respons positif terhadap model EAV / CR. Semua rekan pengembang saya mengatakan apa yang disinggung Jeffrey Kemp di bawah ini: "entitas baru harus dimodelkan dan dirancang oleh seorang profesional" (diambil di luar konteks, baca tanggapannya di bawah). Masalahnya adalah:

  • entitas menambah dan menghapus atribut setiap minggu
    (kata kunci pencarian mendikte atribut masa depan)
  • entitas baru tiba setiap minggu
    (produk dirakit dari bagian-bagian)
  • entitas lama menghilang setiap minggu
    (diarsipkan, kurang populer, musiman)

Pelanggan ingin menambahkan atribut ke produk karena dua alasan:

  • departemen / pencarian kata kunci / grafik perbandingan antara produk sejenis
  • konfigurasi produk konsumen sebelum pembayaran

Atribut harus memiliki makna, bukan hanya pencarian kata kunci. Jika mereka ingin membandingkan semua kue yang memiliki "frosting krim kocok", mereka dapat mengeklik kue, klik tema ulang tahun, klik hiasan krim kocok, lalu centang semua kue yang menarik karena mengetahui bahwa semua kue memiliki frosting krim kocok. Ini tidak khusus untuk kue, hanya sebuah contoh.

Zachary Scott
sumber
Mengapa Anda tidak bisa hanya memiliki tabel 'kategori' dengan kunci asing yang merujuk ke dirinya sendiri?
Noel Kennedy
29
Tidak aman, juga tidak tepat, untuk mengatakan bahwa model database EAV buruk, karena cocok untuk beberapa aplikasi.
spencer7593
Bagaimana jika Anda mendekorasi berbagai objek dengan berbagai properti, mewarisi dari induk seperti di Entity Framework 4? Bagaimana cara menahan benda-benda itu?
Zachary Scott
1
Kembali ke artikel yang sangat bagus ini tentang pengalaman seorang konsultan dengan sistem yang didasarkan pada versi ekstrim EAV. Membacanya! simple-talk.com/opinion/opinion-pieces/bad-carma
Jeffrey Kemp
1
EAV adalah model database yang sangat layak. Saya sedang mengerjakan masalah serupa seperti Anda dan solusinya adalah EAV. Saya akan merekomendasikan artikel berikut: sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/…
Sandor

Jawaban:

75

Ada beberapa pro dan kontra umum yang dapat saya pikirkan, ada situasi di mana yang satu lebih baik dari yang lain:

Opsi 1, Model EAV:

  • Pro: lebih sedikit waktu untuk merancang dan mengembangkan aplikasi sederhana
  • Pro: entitas baru mudah ditambahkan (bahkan mungkin ditambahkan oleh pengguna?)
  • Pro: komponen antarmuka "generik"
  • Kontra: kode kompleks diperlukan untuk memvalidasi tipe data sederhana
  • Kontra: SQL yang jauh lebih kompleks untuk laporan sederhana
  • Kontra: laporan yang kompleks bisa menjadi hampir tidak mungkin
  • Kontra: kinerja yang buruk untuk kumpulan data besar

Opsi 2, Memodelkan setiap entitas secara terpisah:

  • Kontra: lebih banyak waktu yang dibutuhkan untuk mengumpulkan persyaratan dan desain
  • Kontra: entitas baru harus dimodelkan dan dirancang oleh seorang profesional
  • Con: komponen antarmuka kustom untuk setiap entitas
  • Pro: batasan tipe data dan validasi mudah diterapkan
  • Pro: SQL mudah ditulis, mudah dipahami, dan debug
  • Pro: bahkan laporan yang paling rumit pun relatif sederhana
  • Pro: kinerja terbaik untuk kumpulan data besar

Opsi 3, Kombinasi (model entitas "dengan benar", tetapi tambahkan "ekstensi" untuk atribut khusus untuk beberapa / semua entitas)

  • Pro / Kontra: lebih banyak waktu yang dibutuhkan untuk mengumpulkan persyaratan dan desain daripada opsi 1 tetapi mungkin tidak sebanyak opsi 2 *
  • Kontra: entitas baru harus dimodelkan dan dirancang oleh seorang profesional
  • Pro: atribut baru mungkin dengan mudah ditambahkan nanti
  • Kontra: kode kompleks diperlukan untuk memvalidasi tipe data sederhana (untuk atribut khusus)
  • Kontra: komponen antarmuka khusus masih diperlukan, tetapi komponen antarmuka umum dapat digunakan untuk atribut khusus
  • Kontra: SQL menjadi kompleks segera setelah atribut khusus apa pun disertakan dalam laporan
  • Kontra: kinerja yang baik secara umum, kecuali Anda mulai perlu mencari atau melaporkan berdasarkan atribut khusus

* Saya tidak yakin apakah Opsi 3 akan menghemat waktu dalam fase desain.

Secara pribadi saya akan condong ke opsi 2, dan menghindari EAV sedapat mungkin. Namun, untuk beberapa skenario, pengguna memerlukan fleksibilitas yang disertakan dengan EAV; tapi ini harus dibayar mahal.

Jeffrey Kemp
sumber
Bagaimana jika Anda memiliki tabel tunggal dengan indeks untuk nilai teks 1-n, maka di C # (dalam ram) petakan apa yang Anda inginkan ke apa yang Anda butuhkan. Ini masih akan bekerja seperti EAV, tetapi "kecocokan" adalah model domain. Semacam serialisasi, tetapi Anda dapat menggunakan pilihan SQL pada bidang teks yang diindeks. Tidak ada beberapa pilihan per record. Semua "biaya" terjadi di RAM.
Zachary Scott
1
@Zim, kedengarannya sangat mirip dengan opsi 3. Setiap baris memiliki 1-n kolom ekstra "umum", dan data yang disimpan di dalamnya diinterpretasikan pada tingkat aplikasi. Anda mendapatkan manfaat kinerja karena memiliki semua data untuk satu catatan di satu tempat. Metadata tentang kolom-kolom itu perlu disimpan di suatu tempat, bagaimanapun, dan di sinilah biaya masuk. Tentu, kita dapat menyimpan metadata dalam ram, tetapi masih lebih mahal daripada memiliki domain yang dimodelkan secara langsung dalam kode aplikasi. Pastinya lebih baik dari model EAV yang lengkap!
Jeffrey Kemp
1
+10000 Jawaban bagus. Saat ini orang berhemat pada desain database dan pengumpulan kebutuhan. Mereka lebih suka menulis baris kode seratus kali lebih banyak, yang membutuhkan waktu untuk membuat desain yang bagus.
Tulains Córdova
Anda tidak memerlukan lebih banyak desain untuk opsi relasional (2) daripada opsi EAV (1) jika Anda hanya menyediakan struktur opsi 1. Dan antarmuka relasional adalah generik dari metadata yang menjelaskan struktur itu. Ini menghapus semua opsi 2 Kontra. Namun Anda lupa satu-satunya Con: DDL yang sebenarnya bisa jadi mengelola tabel terlalu lambat.
philipxy
Hai @philipxy, saya tidak mengatakan "lebih banyak desain". Alasan untuk EAV adalah bahwa (mungkin) perancang sistem dapat menghabiskan lebih sedikit waktu untuk mendesain model, menyerahkan pekerjaan desain ini kepada "pengguna" nanti (kurangnya desain profesional ini mengarah ke Kontra yang tercantum untuk Opsi 1) . Jika EAV tidak menghasilkan penghematan bagi desainer yang hanya menambahkan lebih banyak bahan bakar ke api karena menolak EAV begitu saja. Juga, saya tidak setuju bahwa DDL "terlalu lambat" - karena DDL seharusnya hanya jarang diperlukan (yaitu untuk memperbaiki kesalahan dalam model, atau untuk mengimplementasikan fitur baru), kinerjanya seharusnya relatif tidak penting.
Jeffrey Kemp
63

Dapat dikatakan bahwa model database EAV / CR buruk.

Tidak. Hanya saja mereka adalah penggunaan database relasional yang tidak efisien. Penyimpanan kunci / nilai murni berfungsi baik dengan model ini.

Sekarang, ke pertanyaan Anda yang sebenarnya: Bagaimana cara menyimpan berbagai atribut dan membuatnya tetap dapat dicari?

Cukup gunakan EAV. Dalam kasus Anda, ini akan menjadi satu tabel ekstra. mengindeksnya pada nama dan nilai atribut, kebanyakan RDBM akan menggunakan kompresi prefiks untuk pengulangan nama atribut, membuatnya sangat cepat dan ringkas.

EAV / CR menjadi jelek saat Anda menggunakannya untuk menggantikan bidang 'nyata'. Seperti setiap alat, menggunakannya secara berlebihan adalah 'buruk', dan memberikan citra yang buruk.

Javier
sumber
jadi pertanyaannya adalah saya memiliki 15 bidang tambahan untuk salah satu kategori saya dan dalam model eav itu membutuhkan 16 bergabung + tabel utama sehingga membuat 16 bergabung tersisa untuk mencari produk (dan memiliki 16 di mana jika pelanggan ingin) dalam 3-4 juta catatan ( situs web untuk menjual produk bekas oleh orang-orang) jadi perlu kinerja rendah?
babak faghihian
2
Jika "bidang tambahan" ini sudah ditentukan, maka ini paling baik dilakukan sebagai "bidang nyata". Dan tentu saja, melakukan jumlah gabungan yang tidak terikat dalam kueri yang besar akan menjadi beban berat (tetapi mungkin masih oke!). Apa yang telah saya lakukan pada proyek yang padat metadata adalah mengizinkan sejumlah "tag" (sebagai catatan EAV) per "item utama", tetapi "kueri besar" hanya mengambil beberapa nama tagnan yang telah ditentukan, menjaga jumlah gabungan tetap terbatas (saat ini tipikal hanya 4 tag dan sekitar 5 gabungan lainnya), dan ketika pengguna memilih item tertentu, maka itu mengambil semua yang terkait, tetapi untuk satu item.
Javier
tetapi tentu saja, sistem spesifik tersebut saat ini sedang di-porting ke suatu hstorebidang (hanya salah satu alasan mengapa kami menggunakan PostgreSQL)
Javier
15
// Pada titik ini, saya ingin meluangkan waktu sejenak untuk berbicara dengan Anda tentang format Magento / Adobe PSD .
// Magento / PSD bukanlah platform / format e-niaga yang baik . Magento / PSD bahkan bukan platform / format e-niaga yang buruk . Menyebutnya seperti itu akan menjadi
// menghina platform / format e-niaga buruk lainnya , seperti Zencart atau OsCommerce. Tidak, Magento / PSD adalah platform / format e-niaga yang buruk . Memiliki
// Bekerja pada kode ini selama beberapa minggu sekarang, kebencian saya pada Magento / PSD telah berkembang menjadi api yang berkobar
// Itu membara dengan gairah sengit sejuta matahari.

http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107

Model internal paling aneh, seperti seseorang memasukkan skema ke dalam permainan boggle, menyegelnya dan memasukkannya ke dalam pengocok cat ...

Dunia nyata: Saya sedang mengerjakan aplikasi pemenuhan midware dan berikut adalah salah satu pertanyaan untuk mendapatkan informasi alamat.

CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id, 
       sales_order_entity.entity_id, 
       CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, 
       GROUP_CONCAT( 
         CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
         ORDER BY sales_order_entity_varchar.value DESC
         SEPARATOR '!!!!!' 
       ) as data
  FROM sales_order_entity
       INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
       INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
   AND sales_order_entity.entity_type_id =12
 GROUP BY sales_order_entity.entity_id
 ORDER BY eav_attribute.attribute_code = 'address_type'

Informasi alamat yang tepat untuk pesanan, malas

-

Ringkasan: Gunakan Magento hanya jika:

  1. Anda diberi banyak uang
  2. Kamu harus
  3. Nikmati rasa sakit
Vee
sumber
Ini adalah posting yang lebih lama tetapi saya berharap saya menemukannya 3 bulan yang lalu ketika saya memulai proyek Magento untuk klien. 1 untuk analogi boggle / paint-shaker!
trevorc
1
Cukup menarik, magento sepertinya merupakan raja jalan dalam hal sistem e-niaga. Mungkin hanya pemasarannya yang sangat bagus
Herr
1
Magento tidak populer karena tingkat pemeliharaannya, tetapi kemampuannya untuk menyesuaikan, memungkinkan siapa pun untuk mengimplementasikan fitur baru tanpa perubahan arsitektur atau sedikit modifikasi. Fitur ini memiliki biaya.
Diego Mendes
Jauhi Magento 2 jika Anda ingin menghindari Triple Pain dan More pain untuk FE dan BE
TheBlackBenzKid
15

Saya terkejut tidak ada yang menyebutkan database NoSQL.

Saya tidak pernah mempraktikkan NoSQL dalam konteks produksi (baru saja menguji MongoDB dan terkesan) tetapi inti dari NoSQL adalah dapat menyimpan item dengan atribut yang berbeda-beda dalam "dokumen" yang sama.

Lucas T.
sumber
Pertimbangkan bahwa penulisan ke MongoDB memerlukan penguncian tingkat database , dan apa artinya itu untuk lalu lintas produksi secara bersamaan.
Bill Karwin
Pertimbangkan bahwa durasi penguncian dalam urutan mikrodetik.
Hello World
12

Di mana kinerja bukan merupakan persyaratan utama, seperti dalam jenis aplikasi ETL, EAV memiliki keunggulan lain: penghematan diferensial.

Saya telah menerapkan sejumlah aplikasi di mana persyaratan yang berlebihan adalah kemampuan untuk melihat riwayat objek domain dari "versi" pertama hingga statusnya saat ini. Jika objek domain tersebut memiliki sejumlah besar atribut, itu berarti setiap perubahan memerlukan baris baru untuk dimasukkan ke dalam tabel yang sesuai (bukan pembaruan karena riwayat akan hilang, tetapi sisipan). Katakanlah objek domain ini adalah Orang, dan saya memiliki 500 ribu Orang untuk dilacak dengan rata-rata 100+ perubahan selama siklus hidup Orang ke berbagai atribut. Pasangkan dengan fakta bahwa rare adalah aplikasi yang hanya memiliki 1 objek domain utama dan Anda akan segera menduga bahwa ukuran database akan cepat tumbuh di luar kendali.

Solusi yang mudah adalah dengan hanya menyimpan perubahan diferensial ke objek domain utama daripada berulang kali menyimpan informasi yang berlebihan.

Semua model berubah seiring waktu untuk mencerminkan kebutuhan bisnis baru. Titik. Menggunakan EAV hanyalah salah satu alat di kotak kami untuk digunakan; tetapi tidak boleh secara otomatis diklasifikasikan sebagai "buruk".

Jerry Jasperson
sumber
2
+1 untuk "Menggunakan EAV hanyalah salah satu alat di kotak kami untuk digunakan; tetapi tidak boleh secara otomatis diklasifikasikan sebagai" buruk "."
Menangkap
Btw, ini disebut SCD (dimensi berubah perlahan). Juga persyaratan bitemporal (kasus khusus Tipe 4 SCD) panggilan skema EAV untuk atribut yang memiliki properti ini. Ingat, 99% NoSQL tidak memiliki native join, jadi jika Anda perlu "live" bergabung dengan jenis data ini, EAV adalah satu-satunya cara.
cowbert
3

Saya berjuang dengan masalah yang sama. Mungkin menarik bagi Anda untuk melihat pembahasan berikut tentang dua solusi e-niaga yang ada: Magento (EAV) dan Joomla (struktur relasional reguler): https://forum.virtuemart.net/index.php?topic=58686.0

Tampaknya, kinerja EAV Magento adalah penghenti yang nyata.

Itulah mengapa saya condong ke struktur yang dinormalisasi. Untuk mengatasi kurangnya fleksibilitas, saya berpikir tentang menambahkan beberapa kamus data terpisah di masa mendatang (XML atau tabel DB terpisah) yang dapat diedit, dan berdasarkan itu, kode aplikasi untuk menampilkan dan membandingkan kategori produk dengan kumpulan atribut baru akan menjadi dihasilkan, bersama dengan skrip SQL.

Arsitektur seperti itu tampaknya menjadi yang terbaik dalam hal ini - fleksibel dan berkinerja pada saat yang sama.

Masalahnya bisa jadi sering menggunakan ALTER TABLE di lingkungan hidup. Saya menggunakan Postgres, jadi MVCC dan DDL transaksionalnya mudah-mudahan akan mengurangi rasa sakit.

aaimnr.dll
sumber
2

Saya masih memilih pemodelan di tingkat atom yang paling rendah untuk EAV. Biarkan standar, teknologi, dan aplikasi yang mengarah pada komunitas pengguna tertentu untuk memutuskan model konten, kebutuhan pengulangan atribut, biji-bijian, dll.

Amanda Xu
sumber
2

Jika ini hanya tentang atribut katalog produk dan karenanya persyaratan validasi untuk atribut tersebut agak terbatas, satu-satunya kelemahan EAV adalah kinerja kueri dan bahkan itu hanya menjadi masalah ketika kueri Anda berurusan dengan beberapa "hal" (produk) dengan atribut, kinerja untuk kueri "beri saya semua atribut untuk produk dengan id 234" sementara tidak optimal masih cukup cepat.

Salah satu solusinya adalah dengan menggunakan database SQL / model EAV hanya untuk sisi admin / edit katalog produk dan memiliki beberapa proses yang mendenormalisasi produk menjadi sesuatu yang membuatnya dapat dicari. Karena Anda sudah memiliki atribut dan karena itu kemungkinan besar Anda ingin faceting, ini bisa berupa Solr atau ElasticSearch. Pendekatan ini pada dasarnya menghindari semua kerugian pada model EAV dan kompleksitas tambahan terbatas pada serialisasi produk lengkap ke JSON saat pembaruan.

bob
sumber
2

EAV memiliki banyak kekurangan:

  1. Penurunan kinerja dari waktu ke waktu Setelah jumlah data dalam aplikasi bertambah melebihi ukuran tertentu, pengambilan dan manipulasi data tersebut cenderung menjadi semakin tidak efisien.
  2. Kueri SQL sangat kompleks dan sulit untuk ditulis.
  3. Masalah Integritas Data. Anda tidak dapat menentukan kunci asing untuk semua bidang yang diperlukan.
  4. Anda harus mendefinisikan dan memelihara metadata Anda sendiri.
Gabriel Voinea
sumber
1. Ini juga berlaku untuk sebagian besar database relasional; inilah mengapa sharding ditemukan. 2. Pemodelan data bisa jadi rumit dan sulit untuk diterapkan. Saya telah menghabiskan berminggu-minggu menunggu perubahan skema kubus OLAP. 3. Sudah banyak dilakukan di perangkat lunak sekarang 4. Anda harus melakukan ini "di ERwin, Excel, dan Visio" saat memodelkan skema relasional.
cowbert
1

Saya memiliki masalah yang sedikit berbeda: alih-alih banyak atribut dengan nilai renggang (yang mungkin merupakan alasan bagus untuk menggunakan EAV), saya ingin menyimpan sesuatu yang lebih seperti spreadsheet. Kolom di sheet bisa berubah, tapi di dalam sheet semua sel akan berisi data (tidak sparse).

Saya membuat serangkaian tes kecil untuk membandingkan dua desain: satu menggunakan EAV, dan yang lainnya menggunakan Postgres ARRAY untuk menyimpan data sel.

EAV masukkan deskripsi gambar di sini

Himpunan masukkan deskripsi gambar di sini

Kedua skema memiliki indeks pada kolom yang sesuai, dan indeks digunakan oleh perencana.

Ternyata skema berbasis larik adalah urutan besarnya lebih cepat untuk penyisipan dan kueri. Dari tes cepat, tampaknya keduanya diskalakan secara linier. Tesnya tidak terlalu teliti. Saran dan garpu diterima - semuanya di bawah lisensi MIT.

z0r
sumber
bagaimana Anda bergabung pada kolom lembar (yaitu vlookup) dengan model array? Tidakkah Anda harus menulis fungsi merge-sort array Anda sendiri? Sangat meragukan itu bisa sebagus penggabungan yang telah dikompilasi sebelumnya jika Anda menggunakan sheet_id + koordinat-x + koordinat-y dari sebuah sel sebagai kunci nilai sel. (untuk meniru excel, buat tabel pencarian untuk koordinat x terlebih dahulu di mana 0-18278 adalah kolom A-ZZZ (excel maxes pada 16384)), lalu Anda dapat memilih nilai di mana sheet_id = uuid dan x-coord = 0 dan y-coord <1001 untuk mendapatkan 1000 baris pertama dari kolom A.
cowbert
@cowbert Anda benar; sebenarnya saya hanya memuat kolom yang saya minati dan bergabung dengan Python. Kendur!
z0r