我推荐具体表继承或类表继承设计。两种设计都满足您的所有四个标准。
在具体表继承中:
- Ipod 存储在具有, , ,
product_ipods
列的表中。ID
Name
Capacity
Generation
- T 恤存储在带有, , ,
product_tshirts
列的表中。ID
Name
Size
Color
- 具体产品类型的定义在 和 的元数据(表定义)
product_ipods
中product_tshirts
。
SELECT SUM(Capacity) FROM product_ipods GROUP BY Generation
;
在类表继承中:
通用产品属性存储在Products
具有列ID
、的表中Name
。
Ipod 存储在product_ipods
带有列product_id
(外键到Products.ID
)、Capacity
、的表中Generation
。
Tshirts 存储在product_tshirts
带有列的表中product_id
(外键到Products.ID
)、Size
、Color
。
具体产品类型的定义在 、 和 的元数据(表定义)products
中。product_ipods
product_tshirts
SELECT SUM(Capacity) FROM product_ipods GROUP BY Generation
;
另请参阅我对“产品表,多种产品,每种产品都有许多参数”的回答,其中我针对您所描述的问题类型描述了几种解决方案。我还详细说明了EAV 为何是一个损坏的设计。
来自@dcolumbus 的重新评论:
使用 CTI,product_ipods 的每一行都会是它自己的价格的变化吗?
products
如果每种类型的产品都有价格,我希望价格列出现在表格中。对于 CTI,产品类型表通常只包含仅与该类型产品相关的属性列。所有产品类型共有的任何属性都会在父表中获取列。
此外,在存储订单行项目时,您是否会将 product_ipods 中的行存储为行项目?
products
在 line-items 表中,存储产品 id,它在表和表中应该是相同的值product_ipods
。
来自@dcolumbus 的评论:
这对我来说似乎是多余的......在那种情况下,我没有看到子表的意义。但即使子表确实有意义,连接是id
什么?
子表的重点是存储所有其他产品类型不需要的列。
连接 id 可以是一个自动递增的数字。子类型表不需要自动增加自己的id,因为它可以使用超级表生成的值。
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
sku VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
price NUMERIC(9,2) NOT NULL
);
CREATE TABLE product_ipods (
product_id INT PRIMARY KEY,
size TINYINT DEFAULT 16,
color VARCHAR(10) DEFAULT 'silver',
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
INSERT INTO products (sku, name, price) VALUES ('IPODS1C1', 'iPod Touch', 229.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 16, 'silver');
INSERT INTO products (sku, name, price) VALUES ('IPODS1C2', 'iPod Touch', 229.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 16, 'black');
INSERT INTO products (sku, name, price) VALUES ('IPODS1C3', 'iPod Touch', 229.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 16, 'red');
INSERT INTO products (sku, name, price) VALUES ('IPODS2C1', 'iPod Touch', 299.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 32, 'silver');
INSERT INTO products (sku, name, price) VALUES ('IPODS2C2', 'iPod Touch', 299.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 32, 'silver');
INSERT INTO products (sku, name, price) VALUES ('IPODS2C3', 'iPod Touch', 299.00);
INSERT INTO product_ipods VALUES (LAST_INSERT_ID(), 32, 'red');