gpt4 book ai didi

mysql - 如何在 Magento mysql 数据库中存储/查询商店/网站特定(或非全局)产品属性?

转载 作者:可可西里 更新时间:2023-11-01 07:49:42 26 4
gpt4 key购买 nike

首先,我知道我应该使用模型而不是直接处理数据库。话虽如此,有谁知道 Magento 是如何处理非全局产品属性的?

我在 core_website 中有 2 个网站: 管理员 (website_id = 0) 和主网站 (website_id =1)。我在core_store也有两家店:管理员(store_id = 0)和默认商店 View (store_id = 0)。似乎产品(或类别?)属性是否在范围内是全局的存储在 catalog_eav_attribute 中。 . is_global .值 0 对应于“商店 View ”的范围,值 1 对应于“全局”,而 2 对应于“网站”。到现在为止还挺好。

现在,如果我想获取商店特定属性的值,例如“名称”( eav_attribute . attribute_id = 71; eav_attribute . backend_type = 'varchar'; catalog_eav_attribute . |104| . |104| 0)对于我所有的产品,你会认为我会做这样的事情:

SELECT *
FROM catalog_product_entity_varchar
WHERE attribute_id = 71
AND store_id = 1

但这没有任何返回。所有的名字实际上都在 is_global 的行中= 0。据我所知,数据库中存储的唯一属性 store_id = 1 是“url_key”和“url_path”。那么 Magento 是如何存储这些值的呢? Magento 如何检索它们?

所有值最初(或也)存储在 store_id 中吗? = 0 作为一种默认值,直到需要存储与该值不同的值?当需要存储与 admin 值不同的 store-specific 值时,magento 是否会使用 store_id 创建一个新行= 1(或任何 store_id)?

如果是这样 - 或者类似的 - 是这种情况,那么 Magento 如何检索商店特定的值?查了吗 store_id . catalog_eav_attribute首先是有问题的属性?如果它是非全局的,那么它可以首先使用 is_global 进行查询。 = 1,如果没有返回,则使用默认值 store_id 查询= 0?

我想我的主要问题是 magento 实际上是如何做到的。其次,为什么 magento 这样做而不是用实际的 store_id 存储值?另外,如果我要写一个查询,我应该同时查询 store_id = 0 和 store_id = 1 并根据属性是否为全局以及 store_id = 1 是否存在值来选择正确的值?

最佳答案

你似乎已经想通了。至少你对事情的处理方式有一个很好的了解。
总结并确认您的怀疑:
所有的属性值都存储在 catalog_product_entity_*哪里*可以是论文中的任何一个:decimal, int, varchar, text, datetime取决于属性类型( backend_type )。

还有其他表格可以保存与层定价和图像相关的数据,但让我们暂时搁置。

属性表定义

每个表都有以下列:

value_id       - just an increment id for the table
entity_type_id - the entity type id for the product (always the same)
attribute_id - reference to the attribute
store_id - reference to the store view
entity_id - reference to the product
value - actual value

这些列有唯一约束 entity_id , attribute_id , store_id .这意味着对于一种产品和一种属性,您的商店 View 只能有一个值。

现在是你正确的部分。
store_id = 0意味着存储在那里的值是一个默认值。
如果没有为特定商店 View 指定值 (store_id >= 1),则将使用该值。
如果该属性设置为全局,则 store_id = 0 的值即使您有 store_id = 1 的值,也会被使用.

示例

要了解如何检索值,请将此代码放在某个文件中并运行它(确保平面目录已禁用 - 稍后会详细介绍,并确保您首先使用 Mage::app() 创建了应用程序的实例):

商店 View 属性
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('name', 'some_name');
echo $collection->getSelect();

上面的代码意味着我要检索名称为 some_name 的产品列表。 .
与集合关联的 sql 查询如下所示:
SELECT 
`e`.*,
IF(at_name.value_id > 0, at_name.value, at_name_default.value) AS `name`
FROM
`catalog_product_entity` AS `e`
INNER JOIN
`catalog_product_entity_varchar` AS `at_name_default`
ON (`at_name_default`.`entity_id` = `e`.`entity_id`) AND
(`at_name_default`.`attribute_id` = '96') AND
`at_name_default`.`store_id` = 0
LEFT JOIN
`catalog_product_entity_varchar` AS `at_name`
ON (`at_name`.`entity_id` = `e`.`entity_id`) AND
(`at_name`.`attribute_id` = '96') AND
(`at_name`.`store_id` = 1)
WHERE
(IF(at_name.value_id > 0, at_name.value, at_name_default.value) = 'some_name')

丑吧?
因为 name属性(在我的例子中为 96)是商店 View 范围属性( is_global = 0)Magento 与表 catalog_product_entity_varchar 连接两次(保存 name 的那个),一次用于当前商店 View ,一次用于 detault 商店 View (id = 0)。添加条件:
 IF(at_name.value_id > 0, at_name.value, at_name_default.value)

因此,如果 store id 1 没有值,请使用默认值。

全局属性

现在让我们看看如果我们按全局属性过滤会发生什么。
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('weight', '1');
echo $collection->getSelect();

打印出来的sql是这样的:
SELECT 
`e`.*,
`at_weight`.`value` AS `weight`
FROM
`catalog_product_entity` AS `e`
INNER JOIN
`catalog_product_entity_decimal` AS `at_weight`
ON (`at_weight`.`entity_id` = `e`.`entity_id`) AND
(`at_weight`.`attribute_id` = '101') AND
(`at_weight`.`store_id` = 0)
WHERE
(at_weight.value = '1')

所以一个单一的连接表 catalog_product_entity_decimal对于商店 id = 0。

网站属性

如果属性的范围是 website一切都像商店 View 范围一样发生,因为 Magento 在保存产品时为当前网站中的每个商店 View 在属性值表中创建一行。
如果您想尝试使用属性 status在上面的例子中。

平面图册
我之前 promise 过一些关于“平面目录”的解释。
出于性能原因,万磁王引入了这个功能(我不记得版本了)。
基本上是一个 cron 运行(或者您可以手动运行它)并将产品和类别的 EAV 方法转换为平面表。您拥有的每个商店 View 对应一个(商店 ID = 0 除外)。
这意味着一个属性将转换为新表中的一列。新表名为 catalog_product_flat_{store_view_id_here} .
当需要某些属性的值时,这避免了大量的左/内连接。
但同样,出于性能原因,并非所有属性都添加为平面表中的列(仅适用于产品。对于类别,所有属性都添加了)。
只有在后端用 Use in product listing 标记的属性被转换成列。
您可以从 System->Configuration->Catalog->Frontend->Use Flat Catalog Product 打开/关闭此功能(或 Use Flat Catalog Category)。

即使打开,平面表也仅用于前端。后端仍然使用 EAV 方法。

结论
我的结论是,编写自己的查询以直接从数据库检索数据几乎是不可能的。您应该使用 magento 提供的模型和集合。它可以节省很多心理健康。

我希望我让你更清楚一些。

关于mysql - 如何在 Magento mysql 数据库中存储/查询商店/网站特定(或非全局)产品属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22024288/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com