EAV veritabanı modeli nedir ?

Eav yapısı bir veritabanı modelidir

Varlık-öznitelik-değer modeli (EAV) olarak tanımlama yapabiliriz. EAV de veritabanında dikey sergilenen değil,

alttaki resim gibi

 

standart_table

yatay giden bir veritabanı şemasıdır.(Alttaki resim gibi)

eav_normal
aslında satır modelleme şeklidir diyebiliriz.

EAV 

EAV Varlık, Attribute ve Değer olarak açılablir .
bu 3 parçaya parçaya bakarak biraz onları daha iyi anlamaya çalışalım.

Varlık (entity) 
Eticaretin ürünler, kategoriler, müşteriler ve siparişler gibi veri öğeleri diyebiliriz.

Özellik (attribute)
Nitelikler, bir işletmenin ait veri öğeleri temsil eder. Örneğin, ürünler için ; adı, fiyat, durumu ,özellikleri, açıklaması ve çok daha fazla özelliklere sahiptir.

Değer (value)
değer ise, adının ne olduğu , fiyatın ne kadar olduğu gibi alanların tutulduğu bölümdür
örneğin normal bir yapıdaki bir e-ticaret sitede sadece ürün bilgisi için bir tabloda bile en az 20 alan olması gerekir
yada urun olarak bir kinetix ayakkabınız var ve bunun 41,42,43 numara bedenleri mavi ,gri , beyaz gibi renkleri vardır
bunu birbiri ile ilişkili tablolarda tutabilirsiniz fakat e-ticaret gibi kompleks ve farklı ürün ve varyantları farklı olan yapıda veritabanında sürekli tabloda alan açmanız yerine göre satırlarda null(boş) olan yerlerin olması gerekecektir böyle bir durumda eav dizayn patternini kullanmak size daha çok esneklik sağlar.

 

Eav veritabanı mimarisini kavramak ilk bakışta son derece zor olabilir bunu uygulama ile anlatmaya çalışacağım.
Eav yapısını kullanan sistem olarak en iyi örnek magento olabilir bkz 
magentonun veritabanı modelini incelemenizi öneririm.

 

Nerede kullanabiliriz?

Birçok ürün ve farklı özelliklere sahip, her bir e-ticaret modellemesinde
Özel veriler için farklı uzantıları destekleyen bir içerik yönetim platformunda
Kullanıcıların talepi üzerine yeni alanlar eklemenizi sağlayan bir ilan sistemi veritabanı modelinde mesela sahibinden.com gibi

Bir crm projesi yaptığınızı düşünelim ve moduler yapıda bir proje olsun bu yapıda sürekli genişleme ve eklenen moduller mesela şikayet modülü olsun
şikayet modülünün elemanları

Numara –>ipi(input TEXT) ->veritabanı türü –> (int(32))
Kişi adı –>tipi(input TEXT) –>veritabanı türü –> (varchar(255))
Şikayet Konusu (tipi(input TEXT) –>veritabanı türü –> (text)

gibi daha iyi anlamak için suitecrm(suitecrm içindeki modules klasoru ve çalışma yapısı) incelenebilir.

Bu gereksinimleri karşılamak için kullanabileceğiniz çözümler aşırı karmaşık ve çok fazla performans gerektirir burada veritabanı şeması yapısını doğru kullanmak önemlidir

bu açıdan eav de veri yapısını bozmadan kolay genişletilebilir ve esnek olması nedeni ile performans olayı da ust düzeydedir

Herhangi bir varlık ile ilişkili özellikleri kaydetmek için esnek bir mekanizma sağlar
Eav tasarımı uygulanabilir hiyerarşik veri bulundrur ,değişiklik ve uygulama için çok az zaman gerektirir.
database şema modelinin tekrar tekrar değiştirilmesine gerek duymaz

eav tabloda kolonlarda varchar ,integer,datetime ,time gibi türleri desteklemez ama kolon içinde tanımlanayabilirsiniz bakınız http://www.jasny.net/articles/an-alternative-way-of-eav-modeling/

standart bir products (ürünler) tablosu
Daha iyi anlamak için aşağıdaki örnekleri deneyiniz.

-- ----------------------------
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`sku` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`size` varchar(255) DEFAULT NULL,
`color` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`model_code` varchar(255) DEFAULT NULL,
`price` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

INSERT INTO `products` VALUES ('1', '100136055', 'Winx KENDRA PK ', '26', 'white', 'KENDRA', '260768', '45.00');
INSERT INTO `products` VALUES ('6', '100136323', 'Winx KENDRA PK Somon', '27', 'pink', 'KENDRA', '260732', '45.00');
INSERT INTO `products` VALUES ('7', '100137675', 'Winx VILMA P black', '42', 'black', 'KENDRA', '260731', '45.00');
INSERT INTO `products` VALUES ('8', '400134347', 'Lumberjack 388004D01 FU ', '44', 'black', '388004D01', '274280', '120.00');

aynı yapının eav modellemesi (eav yapısının çok basit halidir)

DROP TABLE IF EXISTS `eav_attributes`;
CREATE TABLE `eav_attributes` (
`attribute_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`attribute_name` varchar(50) NOT NULL,
PRIMARY KEY (`attribute_id`),
UNIQUE KEY `attribute_name` (`attribute_name`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Table structure for eav_entities
-- ----------------------------
DROP TABLE IF EXISTS `eav_entities`;
CREATE TABLE `eav_entities` (
`entity_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`entity_name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`entity_id`),
UNIQUE KEY `entity_name` (`entity_name`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

-- ----------------------------
-- Table structure for eav_products
-- ----------------------------
DROP TABLE IF EXISTS `eav_products`;
CREATE TABLE `eav_products` (
`entity_id` int(11) unsigned NOT NULL,
`attribute_id` int(11) unsigned NOT NULL,
`value_id` int(11) unsigned NOT NULL,
UNIQUE KEY `entity_attribute_value` (`entity_id`,`attribute_id`,`value_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- ----------------------------
-- Table structure for eav_values
-- ----------------------------
DROP TABLE IF EXISTS `eav_values`;
CREATE TABLE `eav_values` (
`value_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`value_name` varchar(255) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`value_id`),
KEY `value_name` (`value_name`)
) ENGINE=MyISAM AUTO_INCREMENT=29 DEFAULT CHARSET=latin5 COLLATE=latin5_bin;

-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `eav_attributes` VALUES ('5', 'model');
INSERT INTO `eav_attributes` VALUES ('1', 'sku');
INSERT INTO `eav_attributes` VALUES ('2', 'name');
INSERT INTO `eav_attributes` VALUES ('3', 'size');
INSERT INTO `eav_attributes` VALUES ('4', 'color');
INSERT INTO `eav_attributes` VALUES ('6', 'model_code');
INSERT INTO `eav_attributes` VALUES ('7', 'price');
INSERT INTO `eav_entities` VALUES ('1', '100136055');
INSERT INTO `eav_entities` VALUES ('2', '100136323');
INSERT INTO `eav_entities` VALUES ('3', '100137675');
INSERT INTO `eav_products` VALUES ('1', '1', '1');
INSERT INTO `eav_products` VALUES ('1', '2', '2');
INSERT INTO `eav_products` VALUES ('1', '3', '3');
INSERT INTO `eav_products` VALUES ('1', '3', '11');
INSERT INTO `eav_products` VALUES ('1', '3', '12');
INSERT INTO `eav_products` VALUES ('1', '4', '4');
INSERT INTO `eav_products` VALUES ('1', '5', '5');
INSERT INTO `eav_products` VALUES ('2', '1', '14');
INSERT INTO `eav_products` VALUES ('2', '2', '15');
INSERT INTO `eav_products` VALUES ('2', '3', '16');
INSERT INTO `eav_products` VALUES ('2', '4', '17');
INSERT INTO `eav_products` VALUES ('2', '4', '28');
INSERT INTO `eav_products` VALUES ('2', '5', '18');
INSERT INTO `eav_products` VALUES ('2', '6', '19');
INSERT INTO `eav_products` VALUES ('2', '7', '20');
INSERT INTO `eav_products` VALUES ('2', '8', '21');
INSERT INTO `eav_products` VALUES ('2', '9', '22');
INSERT INTO `eav_products` VALUES ('2', '10', '23');
INSERT INTO `eav_products` VALUES ('2', '11', '24');
INSERT INTO `eav_products` VALUES ('2', '12', '25');
INSERT INTO `eav_products` VALUES ('2', '13', '26');
INSERT INTO `eav_products` VALUES ('2', '14', '27');
INSERT INTO `eav_products` VALUES ('2', '15', '28');
INSERT INTO `eav_products` VALUES ('2', '16', '29');
INSERT INTO `eav_values` VALUES ('1', '100136055');
INSERT INTO `eav_values` VALUES ('11', '28');
INSERT INTO `eav_values` VALUES ('2', 'Winx KENDRA PK ');
INSERT INTO `eav_values` VALUES ('3', '26');
INSERT INTO `eav_values` VALUES ('4', 'white');
INSERT INTO `eav_values` VALUES ('5', 'kendra');
INSERT INTO `eav_values` VALUES ('6', '260768');
INSERT INTO `eav_values` VALUES ('7', '45.00');
INSERT INTO `eav_values` VALUES ('13', '30');
INSERT INTO `eav_values` VALUES ('12', '29');
INSERT INTO `eav_values` VALUES ('14', '100136323');
INSERT INTO `eav_values` VALUES ('15', 'Winx KENDRA PK Somon');
INSERT INTO `eav_values` VALUES ('16', '27');
INSERT INTO `eav_values` VALUES ('17', 'pink');
INSERT INTO `eav_values` VALUES ('19', 'KENDRA');
INSERT INTO `eav_values` VALUES ('20', '260732');
INSERT INTO `eav_values` VALUES ('21', '45.00');
INSERT INTO `eav_values` VALUES ('22', 'Winx VILMA P black');
INSERT INTO `eav_values` VALUES ('23', '42');
INSERT INTO `eav_values` VALUES ('24', 'BLACK');
INSERT INTO `eav_values` VALUES ('25', 'KENDRA');
INSERT INTO `eav_values` VALUES ('26', '260731');
INSERT INTO `eav_values` VALUES ('27', '45.00');
INSERT INTO `eav_values` VALUES ('28', 'grey');

Eav Sorgusu (100136323 sku nolu urun bilgilerini verir)

SELECT 
a.attribute_name as 'attribute_name',
v.value_name as 'value_name'
FROM
eav_products as e_products
JOIN
eav_attributes as a ON (e_products.attribute_id = a.attribute_id)
JOIN
eav_values as v ON (e_products.value_id = v.value_id)
WHERE
e_products.entity_id = (select e.entity_id from eav_entities as e where e.entity_name = "100136323")

 

Kaynaklar :

http://www.jasny.net/articles/an-alternative-way-of-eav-modeling/

http://blog.onlinebizsoft.com/mvc-developers-part-6-entity-attribute-value

http://www.jasny.net/articles/an-alternative-way-of-eav-modeling/

http://planet.mysql.com/entry?id=14025

http://mentalfusion.org/examples/MySQL/The+EAV+Database+Modelhttp://mikesmithers.wordpress.com/2013/12/22/the-anti-pattern-eavil-database-design

anahtar / değer yaklaşımına örnek
http://www.codeforest.net/keyvalue-tables-and-how-to-use-them-in-php-and-mysql