Diyelim ki mağaza ürün varlığı, ad, açıklama, resim, fiyat vb. Gibi ortak özelliklere sahiptir, birçok yerde mantıkta yer alır ve saat ve plaj topu gibi (yarı) benzersiz özelliklere sahiptir, saat ve plaj topu gibi tamamen farklı yönleriyle tanımlanacaktır. . Yani EAV, bu (yarı) benzersiz özellikleri depolamak için uygun olacağını düşünüyorum?
Bir EAV yapısının kullanılmasının, ticari kazanç olan çeşitli etkileri vardır.
'Satır için daha az yer kaplıyorsunuz çünkü null
' daha 'karmaşık sorgulara ve modele karşı' 100 sütununuz yok '.
Bir EAV'ye sahip olmak, tipik olarak, değerin, herhangi bir veriyi içine alabileceği bir dize olduğu anlamına gelir. Bunun daha sonra geçerlilik ve kısıt kontrolü üzerinde etkileri var. EAV tablosunda bir şey olarak kullanılan pil sayısını koyduğunuz durumu göz önünde bulundurun. C büyüklüğünde pil kullanan ancak 4'ünden az bir el feneri bulmak istiyorsunuz.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
Burada farkına varılacak şey, değer üzerinde makul bir endeks kullanamayacağınızdır. Ayrıca, değer sütununu farklı amaçlar için tekrar tekrar kullandığından, birinin orada tamsayı olmayan bir şey veya geçersiz bir tamsayı ('-1' pil kullanır) takmasını da önleyemezsiniz.
Bu daha sonra ürün için bir model yazmaya çalışmanın etkileri vardır. Sen güzel Yazılan değerlere sahip olacak ... ama aynı zamanda bir zorunda gidiyoruz Map<String,String>
sadece her türlü orada oturan şeyler onun içinde. Bu daha sonra, XML veya Json'a seri hale getirildiğinde ve bu yapılara karşı doğrulama veya sorgulama yapmaya çalışmanın karmaşıklığının yanı sıra başka etkileri de vardır .
Dikkate alınması gereken düzende bazı alternatifler veya modifikasyonlar, serbest formlu bir anahtar yerine, geçerli anahtarlarla başka bir tabloya sahip olmaktır. Veritabanında string karşılaştırması yapmak yerine, yabancı anahtar kimliklerinin eşitliğine karşı kontrol ettiğiniz anlamına gelir. Anahtarın değiştirilmesi bir noktada yapılır. Bilinen bir anahtar setiniz var, yani enum olarak kullanılabilecekleri var.
Belirli bir ürün sınıfının niteliklerini içeren ilgili tablolara da sahip olabilirsiniz. Bir bakkal departmanı, yapı malzemelerinin ihtiyaç duymadığı (ve bunun tersi) onunla ilişkili çeşitli özelliklere sahip başka bir masaya sahip olabilir.
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Özellikle bir EAV tablosu için çağıran zamanlar vardır .
Her ürünü ve her bir özelliği bildiğiniz, şirketiniz için sadece bir envanter sistemi yazmadığınız durumu düşünün. Şimdi diğer şirketlere satmak için bir envanter sistemi yazıyorsunuz. Sen olamaz her ürünün her özniteliğini biliyorum - onları tanımlamak gerekir.
Çıkar Bir fikir "müşteri tabloyu değiştirmek izin vereceğim" dir ve bu (artık nerede ne olduğunu biliyor çünkü, tablo yapıları için meta-programlama içine ellerinden almak sadece kötü krallar pisliği yapı veya bozuk uygulama, yanlış şeyler yapma erişimine sahipler ve bu erişimin etkileri önemli hale geliyor). MVC4'te bu yol hakkında daha fazlası var : Çalışma zamanında model nasıl oluşturulur?
Bunun yerine, bir EAV tablosuna yönetici arabirimi oluşturun ve kullanılmasına izin verin. Müşteri 'polkadots' için bir giriş oluşturmak isterse, EAV tablosuna girer ve bununla nasıl baş edeceğinizi zaten bilirsiniz.
Bunun bir örneği Redmine veritabanı modelinde görülebilir , custom_fields tablosunu ve custom_values tablosunu görebilirsiniz - bunlar EAV'nin sistemin genişletilmesine izin veren kısımlarıdır.
Tüm tablo yapınızı ilişkiselden ziyade EAV'ye benzeyecek şekilde bulursanız, NoSQL'in (cassandra, redis, Mongo, ...) KV lezzetine bakmak isteyebileceğinizi unutmayın. Bu genellikle ile gelen fark diğer sizin için kullanarak ne ya uygun olabilir veya olmayabilir onların tasarımında ödünleşmeler. Bununla birlikte, bir EAV yapısının amacı ile özel olarak tasarlanmıştır.
Bir envanter yönetimi sistemi için SQL - NoSQL okumak isteyebilirsiniz
Bu yaklaşımın ardından belge yönelimli bir NoSQL veritabanıyla (kanepe, mongo), her envanter öğesinin bir disk üzerinde bir belge olduğunu düşünebilirsiniz ... her şeyi tek bir belgede hızlıca çekerek. Ayrıca, belge tek bir şeyi hızlıca çıkarabilmeniz için yapılandırılmıştır. Öte yandan, tüm belgeleri belirli bir özellik ile eşleşen şeyler için aramak daha az performans gösterebilir (tüm dosyalara karşı 'grep' kullanarak karşılaştırın) ... hepsi değiş tokuş eder.
Diğer bir yaklaşım, birinin tüm ilişkili öğeleriyle bir temele sahip olacağı, ancak daha sonra diğer öğe türleri için kendisine uygulanan ilave nesne sınıflarına sahip olacağı LDAP olacaktır. (bkz . LDAP Kullanarak Sistem Envanteri )
Bu yollardan geçmeyi sonra, olabilecek aynen herşey bazı ödünleşmeler ile gelir gerçi sizin için ... aradıklarını eşleştiğini şey bulmak.