簡體   English   中英

如何在Magento mysql數據庫中存儲/查詢商店/特定於網站(或非全局)的產品屬性?

[英]How are store/website-specific (or non-global) products attributes stored/queried in the Magento mysql database?

首先,我知道我應該使用模型而不是直接使用數據庫。 話雖如此,有沒有人知道Magento如何處理非全球產品屬性?

我在core_website有2個網站:Admin(website_id = 0)和主網站(website_id = 1)。 我在core_store還有兩個存儲:Admin(store_id = 0)和Default Store View(store_id = 0)。 似乎產品(或類別?)屬性是否在范圍內是全局屬性存儲在catalog_eav_attribute is_global 值0對應於“商店視圖”的范圍,值1對應於“全局”,2對應於“網站”。 到現在為止還挺好。

現在,如果我想獲得像“名”特定商店屬性的值( eav_attributeattribute_id = 71; eav_attributebackend_type =“VARCHAR”; catalog_eav_attributeis_global = 0),我所有的產品,你會想我會做這樣的事情:

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

但這沒有任何回報。 所有這些名稱實際上都在store_id = 0的行中。據我所知,數據庫中存儲store_id = 1的唯一屬性是'url_key'和'url_path'。 那么Magento如何存儲這些價值呢? Magento如何檢索它們?

是否所有值最初(或者)都與store_id = 0一起存儲為一種默認值,直到需要存儲與該值不同的值? 當需要存儲與admin值不同的特定於商店的值時,magento是否會創建一個store_id = 1的新行(或者它是什么store_id)?

如果那樣 - 或類似的東西 - 就是這種情況,那么Magento如何檢索特定於商店的值? 它檢查catalog_eav_attribute嗎? is_global首先針對有問題的屬性? 如果它是非全局的,那么它可以首先使用store_id = 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_idattribute_idstore_id 這意味着對於一個產品和一個屬性,您只能擁有一個商店視圖的值。

現在你正確的部分。

store_id = 0表示存儲的值是默認值。
如果沒有為特定商店視圖指定值(store_id> = 1),則將使用此值。
如果該屬性設置為全局,則即使您具有store_id = 1值,也將使用store_id = 0值。

例子

要了解如何檢索值,請將此代碼放在某個文件中並運行它(確保平面目錄已禁用 - 稍后將詳細介紹,並確保首先使用Mage::app()創建應用程序實例Mage::app() ):

存儲視圖屬性

$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屬性(在我的例子中是id 96)是商店視圖范圍屬性( is_global = 0)Magento與表catalog_product_entity_varchar (保存name那個)連接兩次,一次用於當前商店視圖,一次用於detault商店view(id = 0)。 添加條件:

 IF(at_name.value_id > 0, at_name.value, at_name_default.value)

因此,如果商店標識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')

因此,對於商店id = 0,使用表catalog_product_entity_decimal進行單個連接。

網站屬性

如果屬性的范圍是website所有內容都與商店視圖范圍一樣,因為Magento在保存產品時在當前網站中的每個商店視圖的屬性值表中創建一行。
如果您想嘗試使用上面示例中的屬性status

扁平目錄
我早些時候答應了一些關於“平面目錄”的解釋。
出於性能原因,Magneto介紹了這個功能(我不記得版本)。
基本上,cron運行(或者您可以手動運行)並將產品和類別的EAV方法轉換為平面表。 每個商店視圖一個(商店ID = 0除外)。
這意味着一個屬性將轉換為新表中的一列。 新表名為catalog_product_flat_{store_view_id_here}
當想要某些屬性的值時,這避免了許多左/內連接。
但同樣,出於性能原因,並非所有屬性都作為列添加到平面表中(僅適用於產品。對於類別,所有屬性都已添加)。
只有Use in product listingUse in product listing后端標記的屬性才會轉換為列。
您可以從System->Configuration->Catalog->Frontend->Use Flat Catalog Product (或Use Flat Catalog Category )打開/關閉此功能。

即使打開,平面表也只在前端使用。 后端仍然使用EAV方法。

結論
我的結論是,編寫自己的查詢幾乎不可能直接從數據庫中檢索數據。 您應該使用magento提供的模型和集合。 它可以節省很多心理健康。

我希望我能為你做一些更清楚的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM