实体-属性-值(EAV)模型

Magento Alan 11年前 (2014-07-10) 13363次浏览 0个评论 扫描二维码

EAV是英文Entity实体、Attribute属性和Value值的首字母缩写,可能是初学Magento的开发者最难以掌握的部分。虽然并不是只有Magento使用EAV这一概念,在当代的系统中鲜有使用它的,此外Magento对于EAV的运用也并不简单。
实体-属性-值(EAV)模型
那么究竟什么是EAV呢?
为了便于大家理解EAV分别在Magento中起到什么作用,下面对它们进行逐一讲解:

  • Entity:实体代表Magento中产品、客户、分类和订单等的数据项(对象),每个实体都通过独立ID存储在数据库中。
  • Attribute:即对象的属性,属性并不是作为产品表单独一列来进行存放,而是存储在一组单独的数据库表中。
  • Value:顾名思义,是指特定属性所关联的值。

这种设计得以让Magento有很强的灵活性,可以在不修改代码或模板的情况下添加或删除属性。
如果将模型看作是一种数据库的垂直增长的话(添加属性也会增加行的数量),传统的模型则是一种横向增长(添加属性意味着列数的增长),那会导致在添加一个属性时需要进行重新的架构。EAV模型不仅仅允许数据库快速扩充,而且更为高效。因为它只允许非空属性,而不需在数据库中预留空间存储空值。
读者如果对Magento的数据库结构很感兴趣的话,强烈推荐以下网站:http://www.magereverse.com/(注:该站只更新到Magento社区版1.7.0.2)。
添加产品属性可以直接通过在Magento后台添加属性类型(attribute type)即可,如color, size, brand等等,删除同理。
Magento社区版(CE-Community Edition)有八种类型的EAV对象:

  • Customer
  • Customer address
  • Products
  • Product categories
  • Orders
  • Invoices
  • Credit memos
  • Shipments

注:Magento企业版(EE-Enterprise Edition)还有一个称为RMA item的类型,属于RMA系统(Return Merchandise Authorization)的一部分。
当然这种强大的灵活性也是需要付出代价的,应用EAV模型将会使实体数据分布 到大量的表中,例如Proudct模型就占用了40张表。
以下图表显示了一部分保存Magento产品信息用到的表格:
实体-属性-值(EAV)模型
EAV的另一个缺点是在获取大量EAV对象集合时会对性能产生影响并使查询数据库变得更为复杂。这主要是因为数据被分割到多个表中,select一条记录就可能要用到多次join。
我们再以Magento的产品为例,手动创建获取单个产品的查询(以下示例可通过PHPMyAdmin或MySQL Workbench来进行操作,linux可通过yum install phpmyadmin来安装)。
顺便提一下,如果您看了本系列的文章或是构建了自己的Linux环境,可能会出现PHPMyAdmin无法访问的问题,以Alan之前提到的本地使用VirtualBox架设环境为例,需要
1.对apche用户组授权
chown apache:apache /usr/share/phpMyAdmin/ -R
2.如果您用默认的root登录且密码为空的话
nano /etc/phpMyAdmin/config.inc.php
将$cfg[‘Servers’][$i][‘AllowNoPassword’]后的值改为TRUE
3.由于访问时使用的并非Linux本机,默认的localhost是无权访问PHPMyAdmin的,需进行如下修改:
nano /etc/httpd/conf.d/phpMyAdmin.conf
将对应Apache版本Allow from后的值改为All或您机器的IP
首先让我们来看看catalog_product_entity这张表,它实际上是product EAV的主表,因为它包含产品的主要实体记录,首先执行如下指令:

SELECT * FROM <code>catalog_product_entity</code>;

实体-属性-值(EAV)模型
可以看到该表中包含如下列:

  • entity_id:它是产品的唯一标识符,为Magento内部使用
  • entity_type_id:前面也讲过,Magento有product, customer和order等不同的EAV模型类型,对类类型进行标识可以使Magento从对应的表格中获取属性和值。
  • attribute_set_id:产品属性可在本地组成不同的属性集(attribute set),属性集让产品结构具备更强的灵活性,因为各产品不必去使用所有已定义的属性。
  • type_id:Magento中的产品类型分为simple, configurable, bundled, downloadable和grouped等,每种类型都有不同的设置与功能 。
  • sku: Stock Keeping Unit (SKU)可以是一串数字或字母的组合,用于唯一标识网站上所销售的产品,由用户来进行定义。
  • has_options:用于标识产品是否具有自定义选项(如下拉列表和文本框等)。
  • required_options:用于标识自定义项是否为必填或必选项。
  • created_at:该行数据创建的时间。
  • updated_at:数据最后一次被修改的时间。

现在我们已经基本掌握了产品实体表的结构,也了解了各条记录在Magento架设的网站上的一个产品,但还没有SKU和产品类型之外的具体产品信息,那么这些属性又存储在哪里呢?同时Magento又是如何区分哪一个是产品属性哪一个是客户属性呢?
这我们就需要通过如下指令来查看一下eav_attribute表:

SELECT * FROM <code>eav_attribute</code>;

执行后的结果中除产品属性外还可以看到有关customer模型、order模型等属性,幸好我们有一个用于表中过滤数据的键值,可以执行下面的语句:

SELECT * FROM <code>eav_attribute</code> WHERE entity_type_id = 4;

这条查询会返回该表与entity_type_id与产品的entity_type_id(即4)相等的所有属性,在进行进一步讲解之前,我们一些来看一下eav_attribute表的主要列:

  • attribute_id:它是每个属性的唯一标识符,也是此表的主键
  • entity_type_id:此项将属性与特定的EAV模型类型进行关联
  • attribute_code:此项为属性的名称或键名,用于生成魔术方法的getter和setter方法
  • backend_model:后台模型用于向数据库中加载或存储数据的管理
  • backend_type:该项指定属性是否不是保存在默认的EAV表中而是保存在一个特定的表中
  • frontend_model:前端模型负责属性元素在浏览器上的输出效果
  • frontend_input:与前端模型相似,前端输入指定在浏览器上输入项目的类型
  • frontend_label:此项是属性在浏览器上输出的标签或名称
  • source_model:源模型用于向一个属性传递可能存在的值,Magento自带有一些预定义的源模型,如国家,yes或no值,区域等等

下节我们一起来看看在Magento中如何获取数据?

喜欢 (1)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址