假设我有一个在线商店,产品按整数数量或小数重量存储和销售。有不同类型的产品。并非所有项目都相关。我需要决定是否应该将它们放在单独的表中(规范化)或使用一种称为单表继承的技术,它使我能够将所有产品存储在同一个表中,但对每种类型的产品使用不同的模型类。
一个简单的例子。
大米的储存量是每公斤(十进制)而不是每粒(整数)。大米将按公斤(十进制)出售,但您不能出售 1.5 个苹果(十进制)。
这是单表继承的用途还是我错过了它的用途?
数据库示例
CREATE TABLE `product` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`unit` varchar(100) NOT NULL,
`stock` decimal(10,3) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `product` (`name`, `unit`, `stock`)
VALUES
('Rice', 'Kilo', 10.00),
('Apple', 'Each', 500),
('Orange', 'Each', 230),
('Flour', 'Kilo', 55.3),
('Coke', 'Litre', 123.5);
型号(为简单起见,仅显示产品和千克单位类型)
class Product extends CActiveRecord {
...
STUFF
...
protected function instantiate($attributes)
{
switch($attributes['unit'])
{
case 'Kilo':
$class='KiloUnit';
break;
case 'Each':
$class='EachUnit';
break;
case 'Litre':
$class='LitreUnit';
break;
default:
$class=get_class($this);
}
$model=new $class(null);
return $model;
}
}
class KiloUnit extends Product {
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function defaultScope()
{
return array(
'condition'=>"type='Kilo'",
);
}
public function rules(){
array('stock', 'numerical'),
}
public function attributeLabels()
{
return array('stock' => 'Kilo');
}
模型“EachUnit”的规则类似于
array('stock','numerical', 'integerOnly'=>true)
模型“EachUnit”的属性标签类似于
return array('stock' => 'Quantity');
这样,如果我希望使用所有产品,我可以使用以下内容:
$products = Product::model()->findAll();
foreach($products as $p)
{
do something
}
如果我只想处理以公斤为单位类型的产品
$products = KiloUnit::model()->findAll();
foreach($products as $p)
{
do something
}