在本出版物中,我将回顾支持诸如EAV之类的概念的Magento 2 数据结构 。 开发人员有时需要摆脱繁琐的代码,并尝试从雄鹰的飞行高度调查自己的生活地点-这使您可以专注于真正重要或非常重要的事情。 所以我出去了。

缩写EAV被公开为Entity - Attribute - Value (这是针对那些未遵循上面链接的用户)。 EAV的主要“ 好处 ”是在可用于描述事物(实体)的不同属性(属性,参数)的可能数量非常多但属性数量(实际上是指数量)的情况下,有效利用数据库空间单个对象相对较小。 电子商务中这种情况的一个很好的例子是“产品”的概念-产品“ TV ”(屏幕尺寸)的显着属性不同于产品“ 睡袋 ”(最低舒适温度)的显着属性。
那么Magento 2提供了什么以EAV格式存储数据?
'eav_'名称空间
在eav_ Magento 2.3数据库中,有21个带有eav_前缀的表。 所有这些都可以分为三组:
- eav_attribute
- eav_entity
- eav_form
最简单的方法是使用eav_form这些表与UI上某些EAV数据的显示有关,并不直接与数据库中EAV数据的放置有关(我仅考虑数据结构,并且仅从信息存储的角度考虑,而不考虑其显示)。 对于实验,我从数据库中删除了eav_form空间eav_form ,但这并没有阻止我在商店中下订单。 因此,您仍然需要查找该表空间中的数据在何处使用以及Magento需要多少数据才能起作用。
在其余两个中, eav_attribute组引用字母A (属性) , eav_attribute组引用字母E (实体) 。 字母V (alue)在哪里?
实体属性的值必须在表名称后缀中搜索:
- _datetime
- _decimal
- _int
- _text
- _ varchar
您可以看到以以下内容开头的表:
- catalog_category_entity_
- catalog_product_entity_
- customer_address_entity_
- customer_entity_
- eav_entity_
将后缀(5)的数量乘以前缀(5)的数量的简单乘积,便得出了应该存储值数据的表(25)的总数。
'eav_entity_type':实体类型注册表
需要在eav_entity_type表中找到Magento中EAV的开始。 在这里设置将在EAV结构中存储哪些类型的实体属性值。 因此,最初,Magento 2.3为以下八个实体提供此选项:
- customer
- customer_address
- catalog_category
- catalog_product
- order
- invoice
- creditmemo
- shipment
'eav_attribute':属性注册表
下一步是找出这些类型的实体可以表征的属性。 此信息在eav_attribute表中。 属性注册表通过外键对实体类型的寄存器进行了关闭。 在属性注册表中,最初有135个条目属于4种类型的实体:
- customer
- customer_address
- catalog_category
- catalog_product
 
 - 这是在说什么 好吧,至少是其他类型的实体: 
 
- order
- invoice
- creditmemo
- shipment
不要使用EAV结构存储数据。 也就是说,在某个阶段,人们表现出了热情,并计划将EAV用于八种类型的实体,但实际上它们停止在第四位。
'eav_entity_':幽灵空间
eav_entity表eav_entity类似于中国的鬼城 -在9个空间表中,只有两个包含数据:
- eav_entity_type:这是我上面提到的实体类型的寄存器;
- eav_entity_attribute:用于按组组织属性(更接近于数据显示而不是其存储); 该信息与属性本身的关系比与实体的关系更直接(即显然不是来自该教区-它在- eav_attribute_空间中占有一席之地);
其余7个表为空:
- eav_entity
- eav_entity_datetime
- eav_entity_decimal
- eav_entity_int
- eav_entity_store
- eav_entity_text
- eav_entity_varchar
这与尝试统一在一组表( datetime , decimal , int , text , varchar )中存储实体属性值的方式非常相似,而不是试图为每种类型的实体使用5个带有相应后缀的表。 尝试失败? 还是Magento的EAV的未来?

反正 大地是空无一物,黑暗是深渊,上帝的灵 这些表最初并未使用。
属性值类型
在eav_attribute表中设置eav_entity_type类型, eav_attribute在eav_attribute表中设置属性本身及其与相应实体类型的eav_attribute 。 以及如何确定在何处寻找此类实体的属性值?
eav_attribute.backend_type字段将帮助我们解决这一问题。 它显示了属性值的存储位置:
- static :在包含有关实体本身的数据的表中(例如,属性#9-customer.email的值,您需要在email列的customer_entity表中搜索);
对于其余类型,这些值存储在单独的表中,其名称的前缀对应于实体的类型( customer_ _,...),后缀对应于一种数据类型:
- datetime
- decimal
- int
- text
- varchar
即, datetime catalog_product.special_from_date类型的属性#79 catalog_product.special_from_date的值存储在表catalog_product_entity_datetime 。 属性#77 catalog_product.price值在catalog_product_entity_decimal表中。
在eav_attribute表中与值类型有关的有趣之处是什么? 如上所述,此表仅描述了eav_entity_type注册的8种实体类型中的4种eav_entity_type 。 同时,对于诸如customer和customer_address实体,最初定义的所有属性都是static值类型,也就是说,它们是表中的普通列,并且没有利用EAV方法。 表格:
- customer_entity_datetime
- customer_entity_decimal
- customer_entity_int
- customer_entity_text
- customer_entity_varchar
- customer_address_entity_datetime
- customer_address_entity_decimal
- customer_address_entity_int
- customer_address_entity_text
- customer_address_entity_varchar
最初是空的,只能以编程方式使用(即通过管理面板,没有第三方扩展名,无法向这些表中写入任何内容)。
类别的EAV
目录类别-这是Magento中第一个或多或少使用EAV方法的实体。 实体类型为catalog_category ,初始属性的总数为30,其中非静态属性为26。即,只有4个属性( children_count , level , path , position )的值存储在catalog_category_entity表中,其余属性存储在catalog_category_entity_ [ datetime | decimal | int | text | varchar ]。
该集合中的表的结构彼此非常相似,并且与其他类型的实体(客户端,其地址等)的相似表也非常相似:
 CREATE TABLE `catalog_category_entity_datetime` ( `value_id` int(11) NOT NULL AUTO_INCREMENT, `attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0', `store_id` smallint(5) unsigned NOT NULL DEFAULT '0', `entity_id` int(10) unsigned NOT NULL DEFAULT '0', `value` datetime DEFAULT NULL, PRIMARY KEY (`value_id`), UNIQUE KEY `...` (`entity_id`,`attribute_id`,`store_id`), ... ) ... 
对于各种类型的存储值( datetime , decimal , int , text , varchar ),仅value列的类型会更改。 此结构允许您为单独的店面( store_id ) entity_id单独的实体( entity_id )的单独属性( attribute_id )的单独值( value )。
结合Magento的体系结构功能,添加了与店面的其他连接store_id 。 因此,可以为不同的店面定位同一实体的同一属性的值。 目录类别是Magento中的第一个实体,您可以直接使用它们来使用EAV子系统。 您可以通过管理面板设置目录属性的值。

您不仅可以为文本属性提供不同的值(翻译成相应店面的语言),还可以本地化其他类型的属性。 例如,由于预期ru店面的圣诞节假期,属性catalog_category.custom_design_from可以在明年的1月7日和在店面的12月24日设置值。

产品EAV
通常,这与在Magento中为其推出EAV的实体类型相同。 实体类型为catalog_product ,总初始属性为63,非静态为56。支持产品EAV的表的结构类似于目录的表的结构。 但是有一个明显的区别。 对于产品,您可以通过管理面板创建新属性-这是开箱即用的默认Magento功能。 如果Magento根据其他实体的软件填充仅提供其他实体的EAV数据结构,则对于产品,将实现一个界面,使您可以在用户级别(商店经理)执行此操作- 商店/属性/产品 。
对于产品,还有两个与EAV相关的表:
- eav_attribute_set
- eav_attribute_group
总的来说,它们比存储信息更有可能显示信息。 将产品属性组合到一个set ,然后在创建产品时为其分配一组属性,这允许填写例如电视的产品卡,选择与家用电器(甚至是一组称为``电视''的产品)相关的属性。 将属性合并到集合中会发生在商店/属性/产品/属性集中 :

合计
恕我直言,Magento是使用EAV的适用范围非常狭窄的一个很好的例子。 将8个实体( eav_entity_type )的EAV使用标记为书签时,EAV注释仅用于4个实体( eav_attribute ),其中只有2个实体具有真正的EAV属性catalog_category和catalog_product 。 此外,对于catalog_category EAV属性并非用于其预期目的( 用于描述具有与单个实例相关的少量属性的实体的大量不同属性 ),而是用于属性值的“展示位置本地化”( 实体的相同属性集)具有目录属性的能力的“目录类别”对于不同的店面具有不同的含义 )。
EAV的全部使用仅用于catalog_product (尽管也有“店面本地化”的混合,但这是EAV模型的扩展,而不是类别的亵渎)。 但是,通过Magento的产品可以全面展示EAV-Magento应用程序可以安全地用于清楚地展示EAV的原理。