Varlık Özellik Değer Veritabanı ile katı İlişkisel Model E-ticaret karşılaştırması


136

EAV / CR veritabanı modelinin kötü olduğunu söylemek güvenlidir . Bahsedilen,

Soru: Çalışma zamanında değiştirilebilen e-ticaret ürünlerini tanımlayan niteliklerin "sınıflarıyla" başa çıkmak için hangi veritabanı modeli, tekniği veya modeli kullanılmalıdır?

İyi bir E-ticaret veritabanında, seçenek sınıflarını depolayacaksınız (TV çözünürlüğü gibi her TV için bir çözünürlüğe sahip olmakla birlikte, bir sonraki ürün TV olmayabilir ve "TV çözünürlüğü" olmayabilir). Bunları nasıl saklar, verimli bir şekilde arar ve kullanıcılarınızın ürünlerini tanımlayan değişken alanları olan ürün türlerini ayarlamasına izin verir misiniz? Arama motoru, müşterilerin genellikle konsol derinliğine göre TV aradığını tespit ederse, alanlarınıza konsol derinliği ekleyebilir, ardından çalışma zamanında her bir TV ürün türü için tek bir derinlik ekleyebilirsiniz.

İyi bir e-ticaret uygulamaları arasında bir dizi ürün gösterdikleri, daha sonra "TV Çözünürlüğü" nü başlık olarak görebileceğiniz "ayrıntılara inin" yan menülere sahip ve küme bulundu. Birini tıklarsanız, yalnızca bu çözünürlükteki TV'leri gösterir, yan menüden diğer kategorileri seçerek daha fazla ayrıntıya inmenizi sağlar. Bu seçenekler, çalışma zamanında eklenen dinamik ürün özellikleri olacaktır.

Daha fazla tartışma:

Uzun lafın kısası, internette veya aşağıdaki açıklamaları "akademik olarak" düzeltebilecek model açıklamalarında herhangi bir bağlantı var mı? Bir kategori tablosu önerdiği için Noel Kennedy'ye teşekkür ediyorum, ancak ihtiyaç bundan daha büyük olabilir. Önemini vurgulamaya çalışarak, aşağıda farklı bir şekilde tarif ediyorum. Sorunu çözmek için bir bakış açısı düzeltmesine ihtiyacım olabilir veya EAV / CR'ye daha derine inmem gerekebilir.

EAV / CR modeline olumlu yanıtı seviyorum. Geliştiricilerim, Jeffrey Kemp'in aşağıda nelerden bahsettiğini söylüyor: "yeni varlıklar bir profesyonel tarafından modellenmeli ve tasarlanmalıdır" (bağlamdan çıkar, aşağıdaki cevabını okuyun). Problem şu:

  • varlıklar haftalık olarak özellik ekler ve kaldırır
    (arama anahtar kelimeleri gelecekteki özellikleri belirler)
  • Yeni varlıklar haftalık olarak gelir
    (ürünler parçalardan monte edilir)
  • eski varlıklar haftalık olarak kayboluyor
    (arşivlendi, daha az popüler, sezonluk)

Müşteri, iki nedenden ötürü ürünlere özellikler eklemek istiyor:

  • benzer ürünler arasında departman / anahtar kelime arama / karşılaştırma tablosu
  • Ödeme yapmadan önce tüketici ürün yapılandırması

Özelliklerin yalnızca anahtar kelime araması değil, önemi olmalıdır. Eğer bir "çırpılmış krema buzlanma" olan tüm kekleri karşılaştırmak istiyorlarsa, kekleri tıklayabilir, doğum günü temasını tıklayabilir, çırpılmış krema buzunu tıklayabilirler, sonra hepsinin krema buzlanmasına sahip olduklarını bilerek ilginç olan tüm kekleri kontrol edebilirler. Bu keklere özgü değil, sadece bir örnek.


Neden kendini gösteren yabancı anahtarlı bir 'kategori' tablonuz yok?
Noel Kennedy

29
Bazı uygulamalara çok uygun olduğu için, EAV veritabanı modelinin kötü olduğunu söylemek güvenli ve kesin değildir.
spencer7593

Entity Framework 4'teki gibi bir üst öğeden miras alan çeşitli nesneleri çeşitli özelliklerle dekore ederseniz ne olur? Bu nesneleri nasıl ısrar ediyor?
Zachary Scott

1
Sadece bir danışmanın aşırı bir EAV sürümüne dayanan bir sistemle ilgili deneyimi hakkındaki bu mükemmel makaleye dönelim . Oku onu! simple-talk.com/opinion/opinion-pieces/bad-carma
Jeffrey Kemp

1
EAV çok uygulanabilir bir veritabanı modelidir. Senin gibi benzer bir sorun üzerinde çalışıyorum ve çözüm EAV. Aşağıdaki makaleyi tavsiye ederim: sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/…
Sandor

Yanıtlar:


75

Düşünebileceğim birkaç genel artı ve eksiler var, birinin diğerinden daha iyi olduğu durumlar var:

Seçenek 1, EAV Modeli:

  • Pro: basit bir uygulama tasarlamak ve geliştirmek için daha az zaman
  • Profesyonel: Yeni varlıkların eklenmesi kolay (kullanıcılar tarafından bile eklenebilir mi?)
  • Pro: "genel" arayüz bileşenleri
  • Con: basit veri türlerini doğrulamak için karmaşık kod gerekir
  • Con: basit raporlar için çok daha karmaşık SQL
  • Con: Karmaşık raporlar neredeyse imkansız hale gelebilir
  • Con: büyük veri kümeleri için düşük performans

Seçenek 2, Her bir varlığı ayrı ayrı modelleme:

  • Con: gereksinimleri ve tasarımı toplamak için daha fazla zaman gerekiyor
  • Con: yeni varlıklar bir profesyonel tarafından modellenmeli ve tasarlanmalıdır
  • Con: her varlık için özel arayüz bileşenleri
  • Pro: veri tipi kısıtlamaları ve uygulanması kolay doğrulama
  • Pro: SQL'in yazılması, anlaşılması ve hata ayıklanması kolaydır
  • Profesyonel: En karmaşık raporlar bile nispeten basit
  • Pro: büyük veri setleri için en iyi performans

Seçenek 3, Kombinasyon (model varlıkları "düzgün" ancak bazı / tüm varlıklar için özel özellikler için "uzantılar" ekleyin)

  • Pro / Con: gereksinimleri ve tasarımı toplamak için seçenek 1'den daha fazla zaman gerekiyor, ancak belki de seçenek 2 kadar değil *
  • Con: yeni varlıklar bir profesyonel tarafından modellenmeli ve tasarlanmalıdır
  • Pro: yeni özellikler daha sonra kolayca eklenebilir
  • Con: basit veri türlerini doğrulamak için karmaşık kod gerekir (özel özellikler için)
  • Con: özel arayüz bileşenleri hala gerekli, ancak özel öznitelikler için genel arayüz bileşenleri mümkün olabilir
  • Con: Bir rapora herhangi bir özel özellik eklendiğinde SQL karmaşık hale gelir
  • Con: özel özelliklere göre arama yapmaya veya raporlamaya başlamadığınız sürece genellikle iyi performans

* Seçenek 3'ün tasarım aşamasında herhangi bir zamandan tasarruf edip etmeyeceğinden emin değilim.

Şahsen ben seçenek 2 doğru eğilir ve mümkün olduğunca EAV önlemek. Ancak, bazı senaryolar için kullanıcıların EAV ile birlikte gelen esnekliğe ihtiyaçları vardır; ama bu büyük bir maliyetle geliyor.


1-n metin değerleri için dizinleri olan tek bir tablonuz varsa, C # (ram cinsinden) eşlemesine ihtiyacınız olan şeyi eşleyin. Yine de bir EAV gibi çalışır, ancak "eşleşmeler" etki alanı modelleri olur. Bir serileştirme gibidir, ancak dizine alınmış metin alanlarında SQL seçimlerini kullanabilirsiniz. Kayıt başına çoklu seçim yok. Tüm "maliyet" RAM'de gerçekleşir.
Zachary Scott

1
@Zim, bu seçenek 3'e çok benziyor. Her satırda 1-n fazladan "jenerik" sütun var ve içinde saklanan veriler uygulama düzeyinde yorumlanıyor. Bir kayıt için tüm verileri tek bir yerde bulundurmanın performans avantajını elde edersiniz. Bununla birlikte, bu sütunlarla ilgili meta verilerin bir yerde depolanması gerekir ve bu da maliyetin aktığı yerdir. Tabii, meta verileri koç içinde önbelleğe alabiliriz, ancak yine de alanın doğrudan uygulama kodunda modellenmesinden daha pahalıya mal olur. Yine de tam teşekküllü bir EAV modelinden kesinlikle daha iyi!
Jeffrey Kemp

1
+10000 Harika cevap. Günümüzde insanlar veritabanı tasarımı ve ihtiyaç toplama konusunda eksikler. İyi bir tasarım yapmak için zaman alan yüz kat daha fazla kod satırı yazmayı tercih ederler.
Tulains Córdova

Yalnızca seçenek 1'in yapısını sağlıyorsanız ilişkisel seçenek (2) için EAV seçeneğinden (1) daha fazla tasarıma ihtiyacınız yoktur . İlişkisel arabirim bu yapıyı tanımlayan meta verilerden geneldir. Bu seçenek 2 Eksilerini kaldırır. Ancak gerçek Con: DDL tabloları yönetmek çok yavaş olabilir unuttum.
philipxy

Merhaba @ philipxy, "daha fazla tasarım" demedim. EAV için gerekçe, (muhtemelen) sistem tasarımcısının modeli tasarlamak için daha az zaman harcayarak , bu tasarım çalışmasını daha sonra "kullanıcılara" bırakmasıdır (bu profesyonel tasarım eksikliği, Seçenek 1 için listelenen Eksilere yol açar) . EAV, EAV'ı elden reddetmek için yangına sadece daha fazla yakıt ekleyen tasarımcı için tasarruf sağlamazsa. Ayrıca, DDL'nin "çok yavaş" olduğuna katılmıyorum - çünkü nadiren (yani modeldeki hataları düzeltmek veya yeni özellikler uygulamak için) gerekli olduğundan, performansı nispeten önemsiz olmalıdır.
Jeffrey Kemp

63

EAV / CR veritabanı modelinin kötü olduğunu söylemek güvenlidir.

Hayır değil. Sadece ilişkisel veritabanlarının verimsiz kullanımıdır. Tamamen anahtar / değer deposu bu modelle harika çalışıyor.

Şimdi, asıl sorunuza göre: Çeşitli özellikleri nasıl saklayabilir ve bunları aranabilir tutabilirsiniz?

Sadece EAV kullanın. Sizin durumunuzda tek bir ekstra masa olurdu. hem özellik adına hem de değere göre dizine eklediğinizde, çoğu RDBM özellik adı tekrarlarında önek sıkıştırma kullanır ve bu da onu gerçekten hızlı ve kompakt hale getirir.

EAV / CR, 'gerçek' alanları değiştirmek için kullandığınızda çirkinleşir. Her araçta olduğu gibi, aşırı kullanmak 'kötü' ve kötü bir görüntü veriyor.


bu yüzden soru kategorilerimden biri için 15 ek alanım var ve eav modelinde 16 katılma + ana tabloya ihtiyaç duyuyor, bu yüzden 3-4 milyon kayıtta (ve isterse 16 isterse) sahip olmak için 16 sol katılma yapıyor ( insanlar tarafından ikinci el ürünler satmak için bir web sitesi) bu yüzden perofrmance düşük alır?
babak faghihian

2
Bu "ek alanlar" zaten tanımlanmışsa, en iyi şekilde "gerçek alanlar" olarak yapılacaktır. Ve elbette, büyük bir sorguda sınırsız sayıda birleşim yapmak ağır bir ücret olacaktır (ancak yine de iyi olabilir!). Meta veri ağırlıklı bir projede yaptığım, "ana öğe" başına herhangi bir sayıda "etikete" (EAV kaydı olarak) izin vermektir, ancak "büyük sorgu" yalnızca önceden tanımlanmış bazı takma adlarını seçer ve toplam birleştirme sayısını sınırlar (şu anda tipik sadece 4 etiketleri ve yaklaşık 5 diğer katılır olan) ve kullanıcının seçtiği belirli madde, ne zaman o da ilgili herşeyi fetchs, ancak tek bir öğe için.
Javier

ancak elbette, bu belirli sistem şu anda bir hstorealana taşınmaktadır (PostgreSQL'i kullanma nedenlerimizden sadece biri)
Javier

15
// Bu noktada, sizinle Magento / Adobe PSD formatı hakkında konuşmak için biraz zaman ayırmak istiyorum .
// Magento / PSD iyi bir e-ticaret platformu / biçimi değildir . Magento / PSD , kötü bir e-ticaret platformu / formatı bile değildir . Böyle çağırmak bir
// Zencart veya OsCommerce gibi diğer kötü e-ticaret platformuna / biçimlerine hakaret . Hayır, Magento / PSD bir dipsiz e-ticaret platformu / olduğu biçiminde . sahip olan
// bu kod üzerinde birkaç hafta çalıştım, Magento / PSD için nefretim şiddetli bir ateşe dönüştü
// bir milyon güneşin şiddetli tutkusu ile yanıyor.

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

İç modeller en iyi tuhaftır, birisi şemayı bir boggle oyununa koydu, mühürledi ve bir boya shacker'ına koydu ...

Gerçek dünya: Bir midware yerine getirme uygulaması üzerinde çalışıyorum ve işte adres bilgilerini almak için sorgulardan biri.

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'

Bir sipariş için tembel olarak adres bilgilerini içerir

-

Özet: Magento'yu yalnızca şu durumlarda kullanın:

  1. Size büyük para çuvalları veriliyor
  2. Mecbursun
  3. Acının tadını çıkarın

Bu eski bir yazı ama keşke bunu 3 ay önce bir müşteri için bir Magento projesine başladığımda bulsaydım. Boggle / boya çalkalayıcı benzetmesi için +1!
trevorc

1
Oldukça ilginç, magento, e-ticaret sistemleri açısından yolun kralı gibi görünüyor. Belki de sadece pazarlama çok iyidir
Herr

1
Magento, bakım seviyesi nedeniyle popüler değil, ancak özelleştirme yeteneği, herkesin mimari değişiklikler veya birkaç değişiklik yapmadan yeni özellikler uygulamasına izin veriyor. Bu özellik bir maliyetle birlikte gelir.
Diego Mendes

Hem FE hem de BE için üçlü ağrı ve daha fazla acıdan kaçınmak istiyorsanız Magento 2'den uzak durun
TheBlackBenzKid

15

Kimsenin NoSQL veritabanlarından bahsetmediğine şaşırdım.

NoSQL'i hiç bir üretim bağlamında uygulamamıştım (sadece MongoDB'yi test ettim ve etkilendim), ancak NoSQL'in bütün amacı aynı niteliklere sahip farklı özelliklere sahip öğeleri kaydedebiliyor.


MongoDB'ye yazmanın veritabanı düzeyinde kilitleme gerektirdiğini ve bunun eşzamanlı üretim trafiği için ne anlama geldiğini düşünün .
Bill Karwin

Kilit süresinin mikrosaniye sırada olduğunu düşünün.
Merhaba Dünya

12

Performansın önemli bir gereklilik olmadığı durumlarda, ETL tipi bir uygulamada olduğu gibi, EAV'ın başka bir avantajı vardır: diferansiyel tasarruflar.

Bir alan adı nesnesinin geçmiş "ilk" sürümünden mevcut durumuna görmek için yeteneği bir arching gereksinimi olduğu bir dizi uygulama uyguladım. Bu etki alanı nesnesinin çok sayıda özelliği varsa, bu, her değişikliğin karşılık gelen tablosuna yeni bir satır eklenmesini gerektirdiği anlamına gelir (geçmiş kaybolacağı için bir güncelleme değil, bir ekleme). Diyelim ki bu etki alanı nesnesi bir Kişi ve Kişilerin yaşam döngüsü boyunca çeşitli özelliklere göre ortalama 100+ değişiklikle izleyecek 500 bin Kişim var. Nadir olduğu gerçeği ile çift sadece 1 büyük etki alanı nesnesi olan uygulama ve hızlı bir şekilde veritabanı boyutu hızla kontrol dışına büyüyeceğini tahmin.

Kolay bir çözüm, gereksiz bilgileri tekrar tekrar kaydetmek yerine yalnızca ana etki alanı nesnelerine yapılan diferansiyel değişiklikleri kaydetmektir.

Tüm modeller, zaman içinde yeni iş gereksinimlerini yansıtacak şekilde değişir. Dönemi. EAV kullanmak, kutumuzdaki araçlardan sadece biridir; ancak hiçbir zaman otomatik olarak "kötü" olarak sınıflandırılmamalıdır.


2
+1 "EAV kullanmak, kutumuzdaki kullanılacak araçlardan yalnızca biridir; ancak asla otomatik olarak" kötü "olarak sınıflandırılmamalıdır."
Katolikler

Btw, buna SCD (yavaşça değişen boyutlar) denir. Ayrıca bitemporal gereksinimler (Tip 4 SCD'nin özel bir örneği), bu özelliğe sahip olan öznitelikler için EAV şemasını gerektirir. Unutmayın, NoSQL'in% 99'unda yerel bağlantı yoktur, bu nedenle bu tür verilerle "canlı" birleştirmelere ihtiyacınız varsa, EAV tek yoludur.
cowbert

3

Aynı sorunla mücadele ediyorum. Mevcut iki e-ticaret çözümü hakkındaki şu tartışmaya göz atmanız ilginç olabilir: Magento (EAV) ve Joomla (düzenli ilişkisel yapı): https://forum.virtuemart.net/index.php?topic=58686.0

Görünüşe göre Magento'nun EAV performansı gerçek bir gösterici.

Bu yüzden normalleştirilmiş bir yapıya yöneliyorum. Esneklik eksikliğinin üstesinden gelmek için, gelecekte düzenlenebilecek bazı ayrı veri sözlüğü (XML veya ayrı DB tabloları) eklemeyi düşünüyorum ve buna dayanarak, ürün kategorilerini yeni özellikler kümesi ile görüntülemek ve karşılaştırmak için uygulama kodu SQL komut dosyalarıyla birlikte üretildi.

Böyle bir mimari bu durumda tatlı noktası gibi görünüyor - aynı zamanda esnek ve performanslı.

Sorun ALTER TABLE'ın canlı ortamda sık kullanılması olabilir. Postgres kullanıyorum, bu yüzden MVCC ve işlemsel DDL umarım acıyı hafifletecek.


2

Hala EAV için en düşük anlamlı atom düzeyinde modelleme için oy kullanıyorum. İçerik modellerine, niteliklerin, tahılların vb. Tekrarlama gereksinimlerine karar vermek için belirli kullanıcı topluluğuna yönelik standartların, teknolojilerin ve uygulamaların kullanılmasına izin verin.


2

Sadece ürün kataloğu öznitelikleri hakkında ve dolayısıyla bu öznitelikler için doğrulama gereksinimleri oldukça sınırlıysa, EAV'ın tek gerçek dezavantajı sorgu performansıdır ve hatta bu, sorgunuz özniteliklere sahip birden çok "şey" (ürün) ile ilgileniyorsa, bu bir sorundur, sorgusu için performans bana "id 234 ile ürün için tüm nitelikleri vermek" iken optimal değil hala çok hızlı.

Bir çözüm, SQL veritabanı / EAV modelini sadece ürün kataloğunun admin / edit tarafı için kullanmak ve ürünleri aranabilir hale getiren bir şeyde denormalize eden bir işlem yapmaktır. Zaten nitelikleriniz olduğundan ve bu nedenle yüzleşmeyi istemeniz büyük olasılıkla, bu bir şey Solr veya Elastik Arama olabilir. Bu yaklaşım, temel olarak EAV modelinin tüm olumsuzluklarını önler ve eklenen karmaşıklık, güncelleme sırasında eksiksiz bir ürünün JSON'a serileştirilmesiyle sınırlıdır.


2

EAV'ın birçok dezavantajı vardır:

  1. Zaman içindeki performans düşüşü Uygulamadaki veri miktarı belirli bir boyutun üzerine çıktığında, bu verilerin alınması ve işlenmesi daha az ve daha az verimli hale gelir.
  2. SQL sorguları çok karmaşık ve yazılması zor.
  3. Veri Bütünlüğü problemleri. Gerekli tüm alanlar için yabancı anahtar tanımlayamazsınız.
  4. Kendi meta verilerinizi tanımlamanız ve sürdürmeniz gerekir.

1. Bu, çoğu ilişkisel veritabanı için de geçerlidir; bu yüzden parçalama icat edildi. 2. Veri modelleme karmaşık ve uygulanması zor olabilir. OLAP küp şeması değişikliklerini beklemek için haftalarca harcadım. 3. Zaten çoğunlukla yazılımda zaten yapılmış 4. Yine de ilişkisel bir şema modelleme yaparken "ERwin, Excel ve Visio" bunu yapmak zorunda.
cowbert

1

Biraz farklı bir sorun var: seyrek değerleri (muhtemelen EAV kullanmak için iyi bir neden) birçok öznitelik yerine, daha çok bir elektronik tablo gibi bir şey saklamak istiyorum. Sayfadaki sütunlar değişebilir, ancak bir sayfa içinde tüm hücreler veri içerir (seyrek değil).

İki tasarımı karşılaştırmak için küçük bir test seti yaptım : biri EAV, diğeri ise hücre verilerini depolamak için Postgres ARRAY kullanarak.

EAV resim açıklamasını buraya girin

Dizi resim açıklamasını buraya girin

Her iki şemanın da uygun sütunlarda dizinleri vardır ve dizinler planlayıcı tarafından kullanılır.

Dizi tabanlı şemanın hem eklemeler hem de sorgular için daha hızlı bir büyüklük sırası olduğu ortaya çıktı . Hızlı testlerden, her ikisinin de doğrusal olarak ölçeklendiği görülüyordu. Ancak testler çok kapsamlı değil. Öneriler ve çatallar hoş geldiniz - MIT lisansı altındalar.


dizi modeliyle sayfa sütunlarında (yani vlookup) nasıl birleştiniz? Kendi dizi birleştirme-sıralama işlevinizi yazmak zorunda değil misiniz? Bir hücrenin hücre değerinin anahtarı olarak sheet_id + x-koordinat + y-koordinatını kullandıysanız, önceden derlenmiş birleştirme sıralaması kadar iyi olabilir. (excel'i taklit etmek için, 0-18278'in A-ZZZ sütunları (16384'te maksimum değeri çıkar) olduğu x koordinatları için bir arama tablosu önceden oluşturun), bu durumda sheet_id = uuid ve x-coord = 0 ve y-coord değerlerini seçebilirsiniz. <1001 ilk A. sütun
satırını

@cowbert haklısın; Aslında ben sadece ilgilendiğim sütunları yüklemek ve Python katılmak. Gevşek!
z0r
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.