[转]Magento产品属性设置与数据库设计分析

原创文章 永久链接:http://blog.ifeeline.com/577.html
产品的默认属性(字段),Catalog->Attributes->Manage Attributes 或 Manage Attribute Sets都是针对产品实体的。虽然使用EAV模型的实体不仅仅是产品实体,但是只有产品实体提供了添加自定义属性的功能。

下面这个就是一个产品必须具备的属性:
Magento产品属性组

接下来这个ER图涉及三十多个表:
Magento目录产品ER图

Magento实现的目录产品模型到达了一定复杂度(主要是EAV模型引入)。Magento中的EAV模型,必定有一个eav_entity_type和至少一个eav_attribute_set(它也是eav_entity_type相关的)。事实上,只有产品实体的类型设置了多个属性集(创建一个产品时首先要求选择属性集),其它的EAV实体类型也可以设置多个属性集,但是Magento没有实现(也没有必要),所以,除了产品实体类型,其它的实体类型都仅对应了一个属性集。

看看目录实体属性集合和分组情况:
SELECT et.entity_type_id, et.entity_type_code, es.attribute_set_id, es.attribute_set_name, eg.attribute_group_id, eg.attribute_group_name
FROM eav_entity_type et, eav_attribute_set es, eav_attribute_group eg
WHERE es.entity_type_id = et.entity_type_id
AND es.attribute_set_id = eg.attribute_set_id
ORDER BY et.entity_type_id, es.attribute_set_id, eg.attribute_group_id

Magento属性集合分组情况

Magento中的实体类型,除了产品类型,其它的都只有一个属性集,并且除了目录都只有一个属性组。目录只有一个属性集,这个属性集分了多个组。产品有多个属性集,每个属性集有多个属性组。

目录这三个分组,在创建目录时可以看到:
Magento目录分组

问题:使用Magento提供的方法建立一个EAV模型,它实际会为这个模型建立一个实体类型,然后还会建立一个属性集,在这个属性集中有一个属性组,这个组中是否包含所有已定义的属性呢(自定义属性都会插入eav_attribute中)?

这个问题的答案是:只有定义的属性是系统属性时,才会插入默认的属性组中。在eav_attribute表中有一个字段is_user_defined用来标识是系统属性还是用户自定义属性。

Magento的内置的EAV模型默认的属性都是系统属性。Magento只为产品类型添加自定义属性提供了实现,这些自定义的属性都不是系统属性(可以通过其它方法让它变成系统属性,一般不这样弄),而且添加的自定义属性只是往eav_attribute表中插入了记录,并没有分配到属性组,所以要进入如下界面把自定义属性添加到分组(也可以建立自定义分组):
Magento分配属性到属性组

最右边的是没有分配到当前属性集的属性(注意是当前属性集,属性可以关联到多个不同的集)

还需要注意,不管设置了多少个属性集,系统属性一定都在这个这个属性集的分类中,意思是说,你可以把具备某些特征的产品添加自定义属性(系统属性都会包含),从水平表角度来看,每种属性集的产品,字段(属性)不一样,有些多些字段,有些少些字段,但是基本的字段都必须具备(系统属性),正是如此,产品的EAV模型是一个极致的,几乎完美的实现。

EAV模型的查询已经到达了关系数据库中SQL复杂度的极限。大部分的查询都非常复杂,甚至很难理解。

从关系图中可知,属性分别存放到了以属性类型命名的表中,比如varchar、text等,实际上除了常见的类型,比如MySQL中还提供了枚举和SET类型,由于EAV模型的引入,使得类型丢失,所以为了模拟这两种类型,这里引入了eav_attribute_option。

当添加一个属性时:
Magento添加属性


设置的值都存入eav_attribute和catalog_eav_attribute,注意,这里添加是Products Attribute(不是别的)。

catalog_eav_attribute表结构:


Magento catalog_eav_attribute 表结构

除了以上红色圈出来部分没有提供设置外,其它都设置了。注意is_visible默认是1,is_configurable默认也是1。is_wysiwyg_enabled是针对输入区的类型是否启用编辑器(也没有提供给用户)。[更正:当is_global为1和frontend_input为下拉框时,is_configurable选项就会显示,它专门用来表明是否可以用于可以配置商品]

eav_attribute表结构:


Magento eav_attribute 表结构

这里也有很多字段没有提供给用户设置,有些也是没有必要提供的。比如entity_type_id,记录了属性的实体类型,backend_type虽然没有提供给用户设置,但是在设置frontend_input时会根据选择的值自动设置,它决定了属性的值存储在那个类型表中。

Catalog Input Type for Store Owner表示输入类型,比如下拉块还是单选等,是一个属性输入的方式。如果这里选择的是下拉或多选,那么Manage Label / Options就会多出一个让你填入选项的按钮:
Magento属性选项

这些信息就保存到eav_attribute_option 和 eav_attribute_option_value中。它们分别模拟了枚举类型 和 SET类型。eav_attribute_option_value跟商店相关,每个选项会由于不同语言保存了不同的值。如果属性是下拉或多选,就应该分配值,否则它根本没有意义。

另外,每个属性还有一个Label,它是内部使用的,和商店相关,这些信息写入到eav_attribute_label中,至少要输入一个作为管理使用的标识,其它的不设置也没有问题。

还有如下表没有涉及,查看了下,它们内容是空的,对比了下,估计是自建EAV模型的模板。
Magento EAV模型 模板

EAV是Magento数据库设计的基础,在很多的PHP应用甚至其它语言的应用中,应用EAV模型的非常罕见。这个也是Magento高度可扩展的基础,同时也是它确立王者地位因素之一。同时,EAV模型对资源消耗非常大,这个也是它缓慢的重要原因之一,虽然开启缓存可以有效提升系统性能,但是复杂的消耗资源的联合查询依然非常多发。另外,EAV设计模型的复杂性导致深入的二次开发对开发者要求非常高,难度也非常大。绝大部分所谓的二次开发者,都是只是对模板修修改改而已。Magento使用了很多“新技术”,很多实现构架在Zend Framework之上(注意:magento没有使用Zend Frmaework的MVC实现),代码优良,值得深入研究欣赏。

发表评论

电子邮件地址不会被公开。 必填项已用*标注