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.