假設我有一個網上商店,產品按照整數或小數重量進行庫存和銷售。有不同類型的產品。並非所有項目都是相關的。我需要決定是否應該將它們放在單獨的表中(標準化),還是使用稱爲單表繼承的技術,該技術使我可以將所有產品存儲在同一個表中,但對每種產品使用不同的模型類。Yii:何時使用單表繼承。澄清使用和理解
一個簡單的例子。
水稻將被存放每公斤(十進制),而不是每粒(整數)。 大米會以公斤(十進制)出售,但不能賣出1.5個蘋果(十進制)。
這是單表繼承或我錯過了它是什麼點?
DB實施例
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)
和attributeLabel爲模型「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
}
我同意你的意見,但是將這些數據標準化並將其放入單獨表格的傳統方法會在表格中引入額外的連接,每次需要查詢該連接以確定測量/單元類型。 - 放慢數據庫訪問速度,使前端開發成爲一場噩夢。這就是爲什麼我正在考慮使用單表繼承。 – Gravy
對於您的單位,我可能會將該單位存儲爲枚舉或整數映射到所需的特定模型。但總的來說,是的,這種類型的繼承工作正常。有一個不同的類型(你想要另一個表映射的地方),這會變得非常混亂(考慮子類化一個表。小心如果你最終去那裏:-) – acorncom
@Gravy:緩慢的數據庫訪問?夢魘前端發展?我認爲你在那裏有點戲劇化。提供選項的下拉菜單非常標準,如果您有適當的索引,這些小連接只會將微秒添加到數據庫訪問。你永遠不會看到它對抗網絡流量的噪音。我認爲這屬於不成熟優化的範疇,如果它增加了應用程序的複雜性,那麼這是不值得的。 – jmarkmurphy