前言
Magento的EAV模型非常强大且灵活,但是如果不做优化的话,性能会非常低,因为attributes都存放在附表里,要获取一个entity的attribute,需要表联结一次,如果需要获取多条attributes, 就会产生大量的表联结,势必会对数据库造成压力,对于访问量大的内容,比如catalog_product(商品)、商品列表(catalog_category),Magento core team使用了flat table这种策略来应对,简而言之,就是把需要的attributes的值收集起来,新建一个缓存表,Attribute code作为列名,attribute value作为列的值,这样通过一个SELECT就可以把很多attributes的值查询出来。
缓存表是一把“双刃剑”,虽然解决了性能问题,却造成了一些负面影响: 比如:
- 对系统做了修改,需要重新生成缓存表(reindex),假如商品较多,往往比较耗时
- 新增attribute时,如果要添加进缓存表比较麻烦,且需要reindex
在这里简单介绍一下Magento在新增catalog_product的attribute时应该注意的地方,以及如何设置属性的排序、修改原有属性
新增属性
新增商品属性主要使用的是addAttribute()这个方法。
|
|
这里需要注意的是此函数的第三个参数$attr,它是一个数组,里面规定了新的attribute的各种属性:
- “group” : 商品编辑页面左侧导航栏分组,
- “type” : 字段在MySQL中的类型,例如VARCHAR
- “label” : 该属性在商品编辑页面的label
- “input” : 该属性在商品编辑页面的Input type
- “source” : 如果该属性是(multi)select等类型,需要定义一个source类为它提供选项,如果该属性需要加入缓存表,除了提供选项之外,还需要注意提供该属性在缓存表中的字段名以及如果更新缓存表,后面还要详细说明(注1)
- “global” : 代表属性的生效范围,分别有Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL | SCOPE_WEBSITE | SCOPE_STORE
- “required” : 表示是否为必填项
- “user_defined” : 表示是否为用户添加(相对与系统原有的而言)
- “default” : 该属性的缺省值
- “unique” : 表示该属性是否具有唯一性
- “apply_to” : 表示该属性对哪种商品生效,比如"simple,configurable,bundle"表示该属性对simple和configurable两种商品生效
- “used_in_product_listing” : 表示该属性会添加到缓存表中
注1: 假如新增的attribute的input不是"text",例如select,则需要提过source类,该source类继承Mage_Eav_Model_Entity_Attribute_Source_Abstract,需要实现getAllOptions()方法为attributes提供选项;
另外,如果新增的attribute将要添加到缓存表中,首先"used_in_product_listing"应该设置为1,除此之外,source类还需要实现getFlatColums()方法和getFlatUpdateSelect()方法, getFlatColums()方法规定attribute映射到缓存表中的字段的各项属性,包括 type,unsigned,length,nullable等 getFlatUpdateSelect()方法规定缓存表中的值的更新方式,可参考系统中原有的source类来进行设置
参考例子:
|
|
为属性重新设置排序 新增了商品属性之后,同一个分组中的属性排序很混乱,可以使用addAttributeToGroup()方法重新设置排序:
|
|
新增了attribute之后,往往需要重新生成缓存表,记得要在在magento中reindex一下
修改原有属性
|
|
注意: 这里的$field和addAttribute()方法第三个参数$attr所包含的项目不完全一致,请直接使用eav_attribute表的column名称。