为多对多关系(产品的变体)的组合设计SQL模式
我希望这个标题能有所帮助。我使用MySQL作为我的数据库 我正在建立一个产品数据库,不知道如何处理存储产品变体的价格/SKU。一个产品可能有无限的变化,每个变化组合都有自己的价格/SKU/等 这就是我目前设置产品/变体表的方式:为多对多关系(产品的变体)的组合设计SQL模式,sql,schema,e-commerce,database-schema,entity-attribute-value,Sql,Schema,E Commerce,Database Schema,Entity Attribute Value,我希望这个标题能有所帮助。我使用MySQL作为我的数据库 我正在建立一个产品数据库,不知道如何处理存储产品变体的价格/SKU。一个产品可能有无限的变化,每个变化组合都有自己的价格/SKU/等 这就是我目前设置产品/变体表的方式: PRODUCTS +--------------------------+ | id | name | description | +----+------+--------------+ | 1 | rug | a cool rug | | 2 | cup
PRODUCTS
+--------------------------+
| id | name | description |
+----+------+--------------+
| 1 | rug | a cool rug |
| 2 | cup | a coffee cup |
+----+------+--------------+
PRODUCT_VARIANTS
+----+------------+----------+-----------+
| id | product_id | variant | value |
+----+------------+----------+-----------+
| 1 | 1 | color | red |
| 2 | 1 | color | blue |
| 3 | 1 | color | green |
| 4 | 1 | material | wool |
| 5 | 1 | material | polyester |
| 6 | 2 | size | small |
| 7 | 2 | size | medium |
| 8 | 2 | size | large |
+----+------------+----------+-----------+
(`products.id` is a foreign key of `product_variants.product_id`)
我已使用以下示例数据创建了一个SQLFIDLE:
用户可以输入任何变体名称(product\u variants.variant
),并可以为其分配任何值(product\u variants.value
)用户可以输入的变量/值的数量不应有限制。
这就是我的问题所在:每次有人添加带有以前不存在的变体的产品时,存储每个变体的价格/SKU,而不添加新的表/列。
每种变体的价格可能相同,但SKU对每种产品都是唯一的。
例如,产品1
有6种不同的组合(3种颜色*2种材料),而产品2
只有3种不同的组合(3种尺寸*1)
我考虑将组合存储为文本,即:
+------------+-----------------+-------+------+
| product_id | combination | price | SKU |
+------------+-----------------+-------+------+
| 1 | red-wool | 50.00 | A121 |
| 1 | red-polyester | 50.00 | A122 |
| 1 | blue-wool | 50.00 | A123 |
| 1 | blue-polyester | 50.00 | A124 |
| 1 | green-wool | 50.00 | A125 |
| 1 | green-polyester | 50.00 | A125 |
| 2 | small | 4.00 | CD12 |
| 2 | medium | 4.00 | CD13 |
| 2 | large | 3.50 | CD14 |
+------------+-----------------+-------+------+
但必须有一种更好的、规范化的方法来表示这些数据。假设情况:我希望能够搜索一个低于10美元的蓝色产品。使用上面的数据库结构,不解析文本是不可能的,这是我想要避免的
任何帮助/建议都将不胜感激。这与我不久前看到的另一个问题类似 如果你看一下,你会发现你基本上是在问同样的窄表(基于属性)和宽表问题。我根据场景使用了这两种方法,但我会非常小心您现在实现它的方式。事实上,没有一个好的方法将这些变体与SKU匹配(至少我想不出来),这可能会迫使您更改表 如果您有这么多不同的变体,您可能还需要查看键值数据库或其他一些NoSQL解决方案。我将使用4个表:
generic_product: product_id, name, description
e、 g.1‘地毯’、‘咖啡地毯’/2‘杯子’、‘咖啡杯’
generic_product_property: product_id, property_id, property_name
e、 g.1,10‘颜色’/1,11‘材料’
sellable_product: sku, product_id, price
e、 g.‘A121’,1,50.00/‘A122’,1,45.00
sellable_product_property: sku, property_id, property_value
e、 g.‘A121’、10、‘红色’/‘A121’、11、‘羊毛’/‘A122’、10、‘绿色’/‘A122’、11、‘羊毛’
这将允许用户为他想要的可销售产品定义任何属性
您的应用程序必须使用其业务逻辑确保完整描述了可销售的产品(检查是否为每个适用的通用产品属性定义了可销售的产品属性)。将规范化应用于您的问题,解决方案如下所示。跑过去看看
一般来说,你正在寻找所谓的石斑鱼或垃圾维度。基本上,每一个组合都是一行。@sahalMoidu的模式看起来应该满足您的要求
但是,在对规范化过于关注之前,您需要知道数据库是用于存储数据(事务性的,等等)还是用于获取数据(维度的,报告的,等等)。即使它是一个事务性数据库,您也必须问问自己,通过规范化您想要实现什么 部分问题源于产品和SKU之间的混淆 当您销售“XYZ套衫,M号,蓝色型号”时,后者对应于SKU。它以XYZ套衫(产品)的形式销售,具有一组属性(尺寸和颜色),每个属性都有自己的一组潜在值。并不是所有的后一种可能的组合都能产生有效的效果:你不会发现超薄超长的牛仔裤。SKU、产品、属性、属性值 当用户想要一件10美元的蓝色套衫时,他实际上是在寻找某个产品类别中的SKU 我希望上述内容能澄清您的困惑,以及您的问题和疑问的来源 在模式方面,您需要如下内容:
产品
- #产品标识
- 名字
- 描述
- 价格
- 库存
产品属性
- 产品标识
- #属性标识
- 名字
- 属性标识
- #值\u id
- 价值观
库存单位
- 产品标识
- #sku_id
- 价格
- 名字
- 条形码
- 股票
CREATE TABLE products (
product_id int AUTO_INCREMENT PRIMARY KEY,
name varchar(20),
description varchar(30)
);
INSERT INTO products
(name, description)
VALUES
('Rug', 'A cool rug' ),
('Cup', 'A coffee cup');
-- ========================================
CREATE TABLE variants (
variant_id int AUTO_INCREMENT PRIMARY KEY,
variant varchar(50)
);
INSERT INTO variants
(variant)
VALUES
('color'),
('material'),
('size');
-- ========================================
CREATE TABLE variant_value (
value_id int AUTO_INCREMENT PRIMARY KEY,
variant_id int,
value varchar(50)
);
INSERT INTO variant_value
(variant_id, value)
VALUES
(1, 'red'),
(1, 'blue'),
(1, 'green'),
(2, 'wool'),
(2, 'polyester'),
(3, 'small'),
(3, 'medium'),
(3, 'large');
-- ========================================
CREATE TABLE product_variants (
product_variants_id int AUTO_INCREMENT PRIMARY KEY,
product_id int,
productvariantname varchar(50),
sku varchar(50),
price float
);
INSERT INTO product_variants
(product_id, productvariantname, sku, price)
VALUES
(1, 'red-wool', 'a121', 50),
(1, 'red-polyester', 'a122', 50);
-- ========================================
CREATE TABLE product_details (
product_detail_id int AUTO_INCREMENT PRIMARY KEY,
product_variants_id int,
value_id int
);
INSERT INTO product_details
(product_variants_id, value_id)
VALUES
(1, 1),
(1, 4),
(2, 1),
(2, 5);