先说一下数据库设计的三范式:
第一范式(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;
}
如果想深究一下内部原理可以自行研究一下
博客讨论了数据库设计的三范式以及在大型数据量下联表操作的性能问题。Magento采用反三范式设计,通过创建冗余表(如Grid表)同步展示数据,以提高查询性能。举例说明了订单表的冗余数据同步,并提到可以重写方法来自定义同步内容。
1211

被折叠的 条评论
为什么被折叠?



