先說一下數據庫設計的三範式:
第一範式(1NF):確保每一列的原子性
如果每一列都是不可再分的最小數據單元,則滿足第一範式。
第二範式:非鍵字段必須依賴於鍵字段
如果一個關係滿足1NF,並且除了主鍵以外的其它列,都依賴與該主鍵,則滿足二範式(2NF),第二範式要求每個表只描述一件事。
第三範式:在1NF基礎上,除了主鍵以外的其它列都不傳遞依賴於主鍵列,或者說: 任何非主屬性不依賴於其它非主屬性(在2NF基礎上消除傳遞依賴)
但是數據庫根據三範式進行設計的話就有可能會出現聯表情況,當數據量大的時候聯表是什麼消耗性能的,所以三範式不一定就是最好的,這時候就出現了反三範式,magento裏面就存在很多表是反三範式設計的,也叫冗餘表,就是將展示用的數據全部同步到Grid表中,然後使用的時候就不需要聯表直接查一張表就可以,這樣性能會節省很多的,舉個例子就是Grid表:這裏面拿訂單表來舉例子:
/**
* Init virtual grid records for entity
*
* @return Mage_Sales_Model_Resource_Order
*/
protected function _initVirtualGridColumns()
{
parent::_initVirtualGridColumns();
$adapter = $this->getReadConnection();
$ifnullFirst = $adapter->getIfNullSql('{{table}}.firstname', $adapter->quote(''));
$ifnullMiddle = $adapter->getIfNullSql('{{table}}.middlename', $adapter->quote(''));
$ifnullLast = $adapter->getIfNullSql('{{table}}.lastname', $adapter->quote(''));
$concatAddress = $adapter->getConcatSql(array(
$ifnullFirst,
$adapter->quote(' '),
$ifnullMiddle,
$adapter->quote(' '),
$ifnullLast
));
$this->addVirtualGridColumn(
'billing_name',
'sales/order_address',
array('billing_address_id' => 'entity_id'),
$concatAddress
)
->addVirtualGridColumn(
'shipping_name',
'sales/order_address',
array('shipping_address_id' => 'entity_id'),
$concatAddress
);
return $this;
}
可以重寫繼承這個方法,這樣就可以自己添加自己想要同步的數據了:
protected function _initVirtualGridColumns()
{
parent::_initVirtualGridColumns();
$this->addVirtualGridColumn(
'payment_method',
'sales/order_payment',
array('entity_id' => 'parent_id'),
'{{table}}.method'
);
$this->addVirtualGridColumn(
'mobile',
'sales/order_address',
array('billing_address_id' => 'entity_id'),
'{{table}}.telephone'
);
$this->addVirtualGridColumn(
'country_id',
'sales/order_address',
array('billing_address_id' => 'entity_id'),
'{{table}}.country_id'
);
return $this;
}
如果想深究一下內部原理可以自行研究一下