EAV(實體屬性值)
實體
儲存有關所儲存資料型別的資訊。就 Magento 而言,這是客戶,產品,類別等。
屬性
每個實體的各個屬性,例如姓名,體重,電子郵件地址等。
值
給定實體和屬性的值。例如,我們可以指定客戶實體和電子郵件屬性,然後為其指定值 hello@example.com。
資料庫架構
eav_entity
實體表。
eav_entity_attribute
屬性表。
eav_entity_ {型別}
值表。型別是 datetime,decimals,int,text 和 varchar。
需要注意的是,eav_entity_varchar 表的值型別為 varchar,即使日期或整數更適合該值。
模型與資源模型
Mage / Eav / Model / Resource 中的所有模型都是 Mysql4,是資源模型。
另外還有 Entity / Abstract.php 和 Entity / Setup.php。
平與對比 EAV
EAV 模型更復雜,提供了從多個表中儲存和載入的邏輯,而平面或標準模型相對簡單(傳統)。
標準模型主要通過資料設定器和使用單個表的 getter 管理其屬性。EAV 模型主要管理其屬性模型。標準模型僅將其資料儲存到表中並從中載入。EAV 模型在載入基礎資料後載入所有(或特定集)屬性,並在儲存資料(包括插入,更新和刪除屬性)後儲存屬性。
EAV 資源模型示例
要使用 EAV 儲存模式查詢實體來搜尋字串,可以使用 Mage_Eav_Model_Entity_Abstract。這應該揭示基於 EAV 結構的所有資源模型。但是,生成的列表將包含許多不再使用的 Mage_Sales 模組的過時類。
包含使用 EAV 儲存架構的實體的唯一模組是 Mage_Catalog(類別和產品)和 Mage_Customer(客戶和地址)。
客戶組使用平面表儲存架構。所有銷售實體都通過釋出 Magento 1.4 轉換為平面表實體。
使用 EAV 的原因是實體可以具有不確定數量的屬性,因此保持靈活性。例如,當你向 Customer 實體(它是 EAV 實體)新增新屬性時,不需要更改資料庫表以新增此新屬性。
好處
靈活性資料庫模式不需要隨模型 Quick 更改而實現
缺點
- 低效
通常返回 20 列的查詢將包含 EAV 中的 20 個自聯接。但是,Mage_Eav 模組通常不使用連線來載入屬性值資料。而是使用聯合選擇。聯接僅用於過濾 EAV 集合。
- 沒有子型別之間關係的機制
- 沒有實體子型別的分組
網站和商店範圍
要在 EAV 中處理網站和儲存範圍屬性值,目錄實體上存在 store_id 值,以顯示連結回 core_store 的範圍。與普通商店(商店檢視)一起,還有一個商店'0’,這是全域性價值。當在特定商店上時,系統將首先檢查當前商店上的實體值,然後回退到全域性實體。Mage_Customer EAV 實體沒有 store_id 範圍列。
插入,更新和刪除
要確定是否需要對屬性執行插入,更新或刪除,請對原始物件進行比較。當從資料庫中檢索實體時,原始物件基本上是資料物件的副本。
- 如果該屬性最初存在且其新值不為空; 它更新。
- 如果該屬性最初存在但其新值設定為空; 它刪除了。 - 如果該屬性最初不存在且其新值不為空; 它插入。
屬性管理
屬性模型
屬性模型表示資料庫表單中的屬性,其邏輯是所有屬性的標準,很難更改。
前端模型
屬性與前端的介面,並提供屬性在前端需要的任何邏輯,例如影象上的 getUrl()
方法。
後端模型
這些屬性在儲存到資料庫之前對屬性執行驗證。例如,密碼後端模型在儲存之前將密碼轉換為雜湊。它還會在儲存之前檢查密碼和密碼確認是否匹配。
來源模型
用於填充屬性的可用選項,例如,目錄/ product_status 已啟用和禁用。
所需方法
源模型需要:
<?php
public function getAllOptions();
public function getOptionText($value);
?>
通常只需要實現 getAllOptions()
,因為 getOptionText()
的實現已經存在於抽象源模型 Mage_Eav_Model_Entity_Attribute_Source_Abstract 中。
前端模型不需要方法 getValue()
。
後端模型需要:
<?php
public function getTable();
public function isStatic();
public function getType();
public function getEntityIdField();
public function setValueId($valueId);
public function getValueId();
public function afterLoad($object);
public function beforeSave($object);
public function afterSave($object);
public function beforeDelete($object);
public function afterDelete($object);
public function getEntityValueId($entity);
public function setEntityValidId($entity, $valueId);
?>
所有這些方法都在抽象後端模型 Mage_Eav_Model_Entity_Attribute_Backend_Abstract 中實現。對於自定義後端模型,只需要覆蓋需要自定義的方法。
系統配置源模型
不能用於 EAV 屬性。EAV 源模型實現 getAllOptions 方法,而 adminhtml 源模型實現 toOptionArray()
方法。
預設系統配置源模型可以在 Mage / Adminhtml / Model / System / Config / Source /中找到。
屬性源模型
Attribute Source Models 的目的是提供 select 和 multiselect 屬性的選項和值列表。如果需要,它們還會將列資訊提供給目錄平臺索引器。
要獲取屬性的所有選項列表,請執行以下操作:
<?php
$options = $attribute->getSource()->getAllOptions(false);
// or for admin
$options = $_attribute->getSource()->getAllOptions(true, true);
?>
預設屬性模型
如果沒有將類指定為前端,後端或 - 對於選擇或多選屬性 - 源模型,則使用預設類。
預設屬性前端模型是 Mage_Eav_Model_Entity_Attribute_Frontend_Default。
預設屬性後端模型取決於屬性程式碼,並在方法 Mage_Eav_Model_Entity_Attribute :: _ getDefaultBackendModel()
中確定。
<?php
protected function _getDefaultBackendModel()
{
switch ($this->getAttributeCode()) {
case 'created_at':
return 'eav/entity_attribute_backend_time_created';
case 'updated_at':
return 'eav/entity_attribute_backend_time_updated';
case 'store_id':
return 'eav/entity_attribute_backend_store';
case 'increment_id':
return 'eav/entity_attribute_backend_increment';
}
return parent::_getDefaultBackendModel();
}
?>
如果方法落到最後一行,則使用 Mage_Eav_Model_Entity_Attribute_Backend_Default。
預設源模型在 Mage_Eav_Model_Entity_Attribute_Source_Table 中設定。這在目錄模組屬性模型中設定。永遠不會使用 eav 模組中指定的預設配置源模型。
新增屬性
要新增 EAV 屬性,請通過在安裝程式類中擴充套件來使用 Mage_Eav_Model_Entity_Setup。
addAttribute()
建立屬性,將其新增到組和集(包括預設值),或者如果已存在則進行更新 updateAttribute()
僅更新屬性資料。自定義安裝類可用於擴充套件這些方法,新增其他資料或簡化所需的引數。
平臺
平面目錄屬性由索引器管理:
Mage_Catalog_Model_Resource_Product_Flat_Indexer :: updateAttribute()
Mage_Catalog_Model_Resource_Category_Flat :: synchronize()
如果產品屬性被新增到平面表中(參見 Mage_Catalog_Model_Resource_Product_Flat_Indexer :: getAttributeCodes()
):
靜態(後端型別)可過濾用於產品列表用於促銷規則用於按系統屬性排序每個商店都有一個不同的平面表,每個商店都包含一個不同的商店範圍的實體屬性值。通過為每種語言設定不同的商店來管理多語言值。