“ eav_”表的目的


19

我一直想知道表的含义是什么:

eav_entity  
eav_entity_datetime
eav_entity_decimal
eav_entity_int
eav_entity_store
eav_entity_text

他们总是空的。它们是在1.6之前的版本中创建的,app/code/core/Mage/Eav/sql/eav_setup/mysql4-install-0.7.0.php后来又被带到版本1.6+ 的安装脚本中,/app/code/core/Mage/Eav/sql/eav_setup/install-1.6.0.0.php
我看到有一个资源模型链接到其中一个表Mage_Eav_Model_Resource_Entity_Store(也许还有其他表),但是/没有发生任何变化。

这些表有什么用吗?或者这是其他已启动但尚未实现的“功能”,例如布局版本管理面包屑


3
当我开始学习Magento尤其是EAV时,我发现这些表总是空的。我尝试在线搜索,但也没有得到任何指定的答案。我认为这可能是其他实体表的定义或参考表。但是现在我也热切地等待着答案。谢谢这个问题。:)
MagentoBoy 2014年

@MagentoBoy。当我开始尝试围绕数据库工作时,我还看到了当我开始使用Magento时的情况。我已经5年多了,但我仍然感到困惑。
马里斯(Marius)

..但是你们真的在magento上有很好的技能。.有时,我也使用您的参考来学习和在我的代码中.. magento大约需要7到8个月,而php经验却需要11个月,但仍然感觉像我我的Magento的和需要的初学者学习很多..
MagentoBoy

Answers:


17

我的猜测是,这是开发人员实现“通用”实体/模型的部分遗留和“便利”模式。

如您所述,相关表通常为空。原因是没有一个核心EAV实体使用此“默认”实体表结构。这些是从1.8安装开始的实体表:

mysql> select distinct(entity_table) from eav_entity_type;
+-------------------------+
| entity_table            |
+-------------------------+
| customer/entity         |
| customer/address_entity |
| sales/order             |
| sales/order_entity      |
| catalog/category        |
| catalog/product         |
| sales/quote             |
| sales/quote_address     |
| sales/quote_entity      |
| sales/quote_item        |
| sales/invoice           |
+-------------------------+
11 rows in set (0.00 sec)

使用客户模型为例,我们可以看到,资源模型Mage_Customer_Model_Resource_Customer延伸Mage_Eav_Model_Entity_Abstract

:在此之前,以1.6为客户实体的资源模型,Mage_Customer_Model_Entity_Customer这也延长Mage_Eav_Model_Entity_Abstract

如果我们检查Mage_Eav_Model_Entity_Abstract类,我们会找到一个getEntityTable方法。此方法用于确定在普通CRUD操作期间构建查询时要使用哪个表。另一个有趣的方法是 getValueTablePrefix。它确定用于数据“类型”的表,这些表前缀*_datetime*_decimal*_varchar等。

浏览这些方法的源代码(此处此处)。

public function getEntityTable()
    {
        if (!$this->_entityTable) {
            $table = $this->getEntityType()->getEntityTable();
            if (!$table) {
                $table = Mage_Eav_Model_Entity::DEFAULT_ENTITY_TABLE;
            }
            $this->_entityTable = Mage::getSingleton('core/resource')->getTableName($table);
        }

        return $this->_entityTable;
    }

在上述方法中,我们可以看到,如果实体类型未定义自定义表,则默认为Mage_Eav_Model_Entity::DEFAULT_ENTITY_TABLE。该常量的值是'eav/entity',然后将其转到eav_entity表中(假设应用程序中没有配置的表前缀)。如果没有为给定实体配置任何方法,我提到的第二种方法将作为前缀退回到该表上。如果您检查eav_entity_type表中该value_table_prefix列的值,您会发现它们全都是NULL

public function getValueTablePrefix()
    {
        if (!$this->_valueTablePrefix) {
            $prefix = (string)$this->getEntityType()->getValueTablePrefix();
            if (!empty($prefix)) {
                $this->_valueTablePrefix = $prefix;
                /**
                * entity type prefix include DB table name prefix
                */
                //Mage::getSingleton('core/resource')->getTableName($prefix);
            } else {
                $this->_valueTablePrefix = $this->getEntityTable();
            }
        }

        return $this->_valueTablePrefix;
    }

该方法中的逻辑非常简单,如果未定义值前缀,则使用实体表名称作为前缀。

我认为,由于这些表已经在Magento中使用了很长时间了,所以最好将它们保留在其中以保持向后兼容性,而不是直接删除它们。我认为他们追求的想法是易于使用的实体/模型结构,其他开发人员只需扩展几个类即可,并具有可以通过管理员更改的“动态”属性(请参阅产品目录和客户模型)。不幸的是,上述模式的实现和实践似乎无法很好地扩展并导致问题。我从未见过在野外使用这种结构,可能是由于缺乏文档和示例用例或性能不佳。

我不是核心开发人员(或考古学家),但是我是从代码和数据结构中收集的,希望它有助于阐明一些信息。


1
感谢您的解释。对我来说足够好了。我将尝试创建一个使用这些表的实体,只是为了好玩。
马里乌斯

6

考虑基本的EAV资源模型中的这段代码。

#File: app/code/core/Mage/Eav/Model/Entity/Abstract.php
public function getEntityTable()
{
    if (!$this->_entityTable) {
        $table = $this->getEntityType()->getEntityTable();
        if (!$table) {
            $table = Mage_Eav_Model_Entity::DEFAULT_ENTITY_TABLE;
        }
        $this->_entityTable = Mage::getSingleton('core/resource')->getTableName($table);
    }

    return $this->_entityTable;
}

此方法获取用于存储的基本实体表名称。因此,对于产品的资源模型,此方法将返回catalog_product_entity(假设未设置表名前缀)

这四条线最能说明问题。

#File: app/code/core/Mage/Eav/Model/Entity/Abstract.php
$table = $this->getEntityType()->getEntityTable();
if (!$table) {
    $table = Mage_Eav_Model_Entity::DEFAULT_ENTITY_TABLE;
}

如果实体未设置表,则使用以下常量

#File: app/code/core/Mage/Eav/Model/Entity.php
const DEFAULT_ENTITY_TABLE      = 'eav/entity';

eav/entity然后使用此字符串查找表名称

#File: app/code/core/Mage/Eav/Model/Entity/Abstract.php
Mage::getSingleton('core/resource')->getTableName($table);

这从配置中获取表名。

<!-- File: app/code/core/Mage/Eav/etc/config.xml -->
<entity>
    <table>eav_entity</table>
</entity>

啊哈!如果没有为eav实体类型设置表名,则Magento将使用eav_entity表作为默认存储位置。

最初的Magento工程团队迷上了EAV概念-虽然现代的Magento缩小了EAV概念,但EAV模型是解决许多问题的首选解决方案。

假设/推测最初的预发布EAV实现将所有数据存储在此中央eav_entity类型表(企业平台中的常见模式)中似乎是合理的,而实体类型随后出现。

另一个(令人信服的)可能性是,此功能旨在启用“无表” CRUD模型。从理论上讲,可以插入正确的EAV类型信息,设置模型/资源/收集类,并将数据存储在这些eav_entity表中。Magento不再使用EAV,并且在发布后将精力集中在最终用户功能的工程团队上,这意味着该功能逐渐消失了。尽管我想知道这是否行得通,但我不想依靠它,因为它不是引起很多关注的代码路径,并且TAF涵盖了它的使用也令人怀疑。


1
感谢您的详细解释。我肯定会尝试使用“无表”实体构建模块,以查看其是否有效。向我+1。但是我有义务接受@beeplogic提供的答案,该答案指出了基本相同的内容。他快了5分钟。
马里乌斯

-1

Magento对许多功能(客户,产品等)使用称为“实体属性值”的数据模型。这就是允许系统中动态属性的原因,而不必动态重构和更改表。维基百科上的EAV


谢谢,但这并不能真正回答问题。哪个实体使用问题中提到的表格?我不是在谈论客户,产品或类别。
马里斯(Marius)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.