Upload
khoa-truong-dinh
View
115
Download
1
Embed Size (px)
Citation preview
Magento EAV SystemThe EAV system is one of the most complex part of Magento system.
TRUONG DINH KHOA
Email: [email protected]
Do you know?
MySQL has a hard limit of 4096 columns per table.
Oracle has even less: 1000.
Microsoft SQL Server offers up to 30,000 columns.
Traditional model
In a traditional database model, tables have a fixed number of columns
products
product_id
name
price
atribute_1
……
product_id
name price attribute_1
… …
000001 T-Shirt 16.9 Value 1 … …
000002 EAV Book 19 Value 2 … …
EAV Model
However, if entities have a huge of possible attributes? What happens? E.g. a product has a lot of attribute: price, name, color, image, tax, manufacturer , attribute_1… attribute_n, etc..
EAV Model
The problem can be addressed by EAV (row modelling).
Traditional model : adding more attributes => more columns.
EAV model: adding more attributes => more rows.
EAV stands for entity, attribute and value.
Many cloud computing platforms (Amazon, Google, Microsoft, etc.) offer EAV Model as featuring data stores.
EAV Model
“E” in EAV stands for Entity. In Magento case, they are such as product, customer, category, order, etc.
“A” stands for Attribute. These are the individual properties of each of the entities, e.g. name, weight, email address, etc.
“V” stands for Value. The value of any particular attribute.
EAV Model
Magento Model Entity Model
EAV Attribute
Value Table
(varchar)
Value Table(text)
Value Table(int)
Value Table(etc)
EAV Model
For example : Catalog Product
catalog_product_entity
(entity_type_id)
eav_attribute(entity_type_id,
attribute_id)
catalog_product_entity_attribute_varchar
(entity_type_id, attribute_id)
catalog_product_entity_attribute_text(entity_type_id, attribute_id)
catalog_product_entity_attribute_int(entity_type_id, attribute_id)
catalog_product_entity_attribute_etc(entity_type_id, attribute_id)
Creating simple raw sql
SELECT a list of product
3 tables:
catalog_product_entity ,
eav_attribute,
catalog_product_entity_varchar
Creating simple raw sql
-eav_attribute:
+attribute_id: unique identifier and primary key of table.
+entity_type_id: relates each attribute to a EAV model type.
+attribute_code: the name or key of attributes.
+….
-catalog_product_entity:
+entity_id: unique identifier of product.
+entity_type_id: identifies each type of EAV model type.
+….
Creating simple raw sql
-catalog_product_entity_varchar
+value_id: unique identifier and primary key
+entity_type_id: this value belongs to product entity.
+attribute_id: a foreign key- references to attribute_id on eav_attribute
+…
Creating simple raw sql
Raw SQL:
SELECT
p.entity_id AS product_id,
var.value AS product_name,
p.sku AS product_sku
FROM
catalog_product_entity p,
eav_attribute eav,
catalog_product_entity_varchar var
WHERE p.entity_type_id = eav.entity_type_id
AND var.entity_id = p.entity_id
AND eav.attribute_code = 'name'
AND eav.attribute_id = var.attribute_id
ORDER BY `name` ASC
What’s next?
Creating a raw sql shows a small piece. It is easy to understand for new Magento developers. But for customizing and maintaining purpose, what programming technique is used?
In a big picture, we need to do more for our software => Magento used Object Relational Mapping (ORM) system.
Magneto ORM System
Object-relational mapping (ORM, O/RM, and O/R mapping) in computersoftware is a programming technique for converting data between incompatible type systems in object-oriented programming languages. This creates, in effect, a "virtual object database" that can be used from within the programming language.https://en.wikipedia.org/wiki/Object-relational_mapping
Magento ORM System
Building a simple query to retrieve products listing:
//Instantiate a product collection:$collection = Mage::getModel('catalog/product')->getCollection();
//Select an attribute:$collection->addAttributeToSelect('name');
//Sort the collection:$collection->setOrder('name', 'asc');
//Load the collection:$collection->load();
//Print the collection
echo $collection->getSelect();
Magento ORM System
SELECT
`e`.*,
IF(at_name.value_id > 0, at_name.value, at_name_default.value) AS `name`,
`price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`,
IF(
price_index.tier_price IS NOT NULL,
LEAST(
price_index.min_price,
price_index.tier_price
),
price_index.min_price
) AS `minimal_price`,
`price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price`
FROM
`catalog_product_entity` AS `e`
LEFT JOIN `catalog_product_entity_varchar` AS `at_name_default`
ON (`at_name_default`.`entity_id` = `e`.`entity_id`)
AND (`at_name_default`.`attribute_id` = '71')
AND `at_name_default`.`store_id` = 0
LEFT JOIN `catalog_product_entity_varchar` AS `at_name`
ON (`at_name`.`entity_id` = `e`.`entity_id`)
AND (`at_name`.`attribute_id` = '71')
AND (`at_name`.`store_id` = 1)
INNER JOIN `catalog_product_index_price` AS `price_index`
ON price_index.entity_id = e.entity_id
AND price_index.website_id = '1'
AND price_index.customer_group_id = 0
ORDER BY `name` ASC
Magento ORM System
Some differences in comparison with a raw sql:
-There are many columns.
-Getting products in current store: at_name_default`.`store_id` = 0
-Add more conditions: e.g. IF(at_name.value_id > 0, at_name.value, at_name_default.value)
-etc.
Magento ORM SystemThe most useful collection methods
addAttributeToSelect: adding an attribute to entities in a collection
addAttributeToFilter: using to filter a collection ofEAV entities with the specified conditional parameters.
addFieldToFilter: using also to filter a collection, but for non-EAV models, this function is used regularly.
addAttributeToSort: adding an attribute to sort order
etc.
EAV-Advantages
Flexibility.
Don’t need to change database schema when adding new attributes.
Quick to implement.
EAV-Disadvantages
Performance problem: a lot of tables are required when making a query with EAV Model.
Find more…
Thanks you!
Khoa Truong [email protected]
http://www.boolfly.com/
https://github.com/mrkhoa99
https://vn.linkedin.com/in/truongdinhkhoa
http://stackoverflow.com/users/5179786/khoa-truongdinh