我推荐具体表继承或类表继承设计。两种设计都满足您的所有四个标准。
在具体表继承中:
- Ipod 存储在具有, , ,
product_ipods列的表中。IDNameCapacityGeneration
- T 恤存储在带有, , ,
product_tshirts列的表中。IDNameSizeColor
- 具体产品类型的定义在 和 的元数据(表定义)
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_ipodsproduct_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');