Question

I've always wondered what is the meaning of the tables :

eav_entity  
eav_entity_datetime
eav_entity_decimal
eav_entity_int
eav_entity_store
eav_entity_text

They are always empty. They are created in versions before 1.6 in app/code/core/Mage/Eav/sql/eav_setup/mysql4-install-0.7.0.php and later they carried to the install script for versions 1.6+ /app/code/core/Mage/Eav/sql/eav_setup/install-1.6.0.0.php
I saw that there is a resource model linked to one of the tables Mage_Eav_Model_Resource_Entity_Store (maybe there are others) but nothing happens to/with it.

Is there any use to these tables or is this an other "feature" that was started and not implemented like the layout version or admin breadcrumbs for example.

Was it helpful?

Solution

My guess is that it's part legacy and a "convenience" pattern for developers to implement "generic" entities/models.

As you've stated, the related tables are usually empty. The reason being is that none of the core EAV entities use this "default" entity table structure. These are the entity tables from a 1.8 install:

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)

Using the Customer model as an example, we can see that the resource model Mage_Customer_Model_Resource_Customer extends Mage_Eav_Model_Entity_Abstract, Source.

Note: Prior to 1.6 the resource model for the customer entity was Mage_Customer_Model_Entity_Customer which also extended Mage_Eav_Model_Entity_Abstract, Source.

If we examine the Mage_Eav_Model_Entity_Abstract class we find a getEntityTable method. This method is used to determine which table to use when building queries during common CRUD operations. Another method that is of interest is getValueTablePrefix. It determines the prefix for the tables for data "type" tables, *_datetime, *_decimal, *_varchar and so on.

Peeking into the source for those methods (here and here).

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;
    }

In the above method we can see that if the the entity type does not define a custom table it defaults to Mage_Eav_Model_Entity::DEFAULT_ENTITY_TABLE. The value of that constant is 'eav/entity', which in turn gets turned into the eav_entity table (assuming there's no configured table prefix in the application). The second method I mentioned falls back on this table as a prefix if none has been configured for the given entity. If you examine the values in the eav_entity_type table for the value_table_prefix column you'll notice that they're all 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;
    }

The logic in the method is rather simple, if no value prefix is defined use the entity table name as the prefix.

I presume that since these tables have been in Magento for so long it's best to leave them in for any backwards compatibility than remove them outright. The idea that I believe they were going for was an easy to use entity/model structure that other developers could just extend a few classes and have these "dynamic" attributes that could be changed via the admin (see catalog products and customer models). Unfortunately the implementation and practice of said pattern doesn't seem to scale well and leads to problems. I've never seen this structure used in the wild, probably due to the lack of documentation and example use cases or poor performance.

I'm no core developer (or archeologist) but that's what I gather from the code and data structures, hopefully it helps shed some light.

OTHER TIPS

Consider this bit of code in the base EAV resource model.

#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;
}

This method grabs the base entity table name to use for storage. So, for a product's resource model, this method will return catalog_product_entity (assuming no table name prefix has been set)

These four line are the most revealing.

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

If the entity doesn't have a table set, the following constant is used

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

This eav/entity string is then used to look up a table name

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

Which plucks the table name from the config.

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

Ah ha! If an eav entity type does not have a table name set, then Magento will use the eav_entity tables as the default storage location.

The original Magento engineering team was enamored of the EAV concept — while modern Magento has scaled this back, EAV models were the preferred solution for many problems.

It seems reasonable to assume/speculate the initial pre-release EAV implementation stored all data in this central eav_entity type table (a common pattern in enterprise platforms), and the entity types came along later.

Another (compelling) possibility is this feature was intended to enable "tableless" CRUD models. In theory, it would be possible to insert the correct EAV type information, setup your model/resource/collection classes, and have data stored in these eav_entity tables. Magento's move away from EAV, and the post-launch focus on the engineering team on end-user features meant this feature faded away into the mist. While I'd be curious if this works, I wouldn't want to rely on it as it's not a code path that's received a lot of attention, and it's doubtful that the TAF covers its use.

Magento uses a data model called "Entity Attribute Value" for many of it's functions (customers, products, etc.). This is what allows dynamic attributes in the system without having to restructure and alter the tables on the fly. EAV On Wikipedia

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top