Magento新增商品属性以及将属性加入Flat table | Magento Add New Product Attribute and Add Attribute to Flat Table

前言

Magento的EAV模型非常强大且灵活,但是如果不做优化的话,性能会非常低,因为attributes都存放在附表里,要获取一个entity的attribute,需要表联结一次,如果需要获取多条attributes, 就会产生大量的表联结,势必会对数据库造成压力,对于访问量大的内容,比如catalog_product(商品)、商品列表(catalog_category),Magento core team使用了flat table这种策略来应对,简而言之,就是把需要的attributes的值收集起来,新建一个缓存表,Attribute code作为列名,attribute value作为列的值,这样通过一个SELECT就可以把很多attributes的值查询出来。

缓存表是一把“双刃剑”,虽然解决了性能问题,却造成了一些负面影响: 比如:

  1. 对系统做了修改,需要重新生成缓存表(reindex),假如商品较多,往往比较耗时
  2. 新增attribute时,如果要添加进缓存表比较麻烦,且需要reindex

在这里简单介绍一下Magento在新增catalog_product的attribute时应该注意的地方,以及如何设置属性的排序、修改原有属性

新增属性

新增商品属性主要使用的是addAttribute()这个方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//file: app\code\core\Mage\Eav\Model\Entity\Setup.php
/**
* Add attribute to an entity type
*
* If attribute is system will add to all existing attribute sets
*
* @param string|integer $entityTypeId
* @param string $code
* @param array $attr
* @return Mage_Eav_Model_Entity_Setup
*/
public function addAttribute($entityTypeId, $code, array $attr){ ... }

这里需要注意的是此函数的第三个参数$attr,它是一个数组,里面规定了新的attribute的各种属性:

  1. “group” : 商品编辑页面左侧导航栏分组,
  2. “type” : 字段在MySQL中的类型,例如VARCHAR
  3. “label” : 该属性在商品编辑页面的label
  4. “input” : 该属性在商品编辑页面的Input type
  5. “source” : 如果该属性是(multi)select等类型,需要定义一个source类为它提供选项,如果该属性需要加入缓存表,除了提供选项之外,还需要注意提供该属性在缓存表中的字段名以及如果更新缓存表,后面还要详细说明(注1)
  6. “global” : 代表属性的生效范围,分别有Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL | SCOPE_WEBSITE | SCOPE_STORE
  7. “required” : 表示是否为必填项
  8. “user_defined” : 表示是否为用户添加(相对与系统原有的而言)
  9. “default” : 该属性的缺省值
  10. “unique” : 表示该属性是否具有唯一性
  11. “apply_to” : 表示该属性对哪种商品生效,比如"simple,configurable,bundle"表示该属性对simple和configurable两种商品生效
  12. “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类来进行设置

参考例子:

1
2
//file: app\code\core\Mage\Eav\Model\Entity\Attribute\Source\Boolean.php
class Mage_Eav_Model_Entity_Attribute_Source_Boolean

为属性重新设置排序 新增了商品属性之后,同一个分组中的属性排序很混乱,可以使用addAttributeToGroup()方法重新设置排序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//file: app\code\core\Mage\Eav\Model\Entity\Setup.php
/**
 * Add or update attribute to group
 *
 * @param int|string $entityType
 * @param int|string $setId
 * @param int|string $groupId
 * @param int|string $attributeId
 * @param int $sortOrder
 * @return Mage_Eav_Model_Entity_Setup
 */
public function addAttributeToGroup($entityType, $setId, $groupId, $attributeId, $sortOrder = null){ ... }

新增了attribute之后,往往需要重新生成缓存表,记得要在在magento中reindex一下

修改原有属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//file: app\code\core\Mage\Eav\Model\Entity\Setup.php
/**
* Update Attribute data and Attribute additional data
*
* @param mixed $entityTypeId
* @param mixed $id
* @param string $field
* @param mixed $value
* @param int $sortOrder
* @return Mage_Eav_Model_Entity_Setup
*/
public function updateAttribute($entityTypeId, $id, $field, $value = null, $sortOrder = null){ ... }

注意: 这里的$field和addAttribute()方法第三个参数$attr所包含的项目不完全一致,请直接使用eav_attribute表的column名称。

Built with Hugo
主题 StackJimmy 设计