Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为多对多关系(产品的变体)的组合设计SQL模式_Sql_Schema_E Commerce_Database Schema_Entity Attribute Value - Fatal编程技术网

为多对多关系(产品的变体)的组合设计SQL模式

为多对多关系(产品的变体)的组合设计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

我希望这个标题能有所帮助。我使用MySQL作为我的数据库

我正在建立一个产品数据库,不知道如何处理存储产品变体的价格/SKU。一个产品可能有无限的变化,每个变化组合都有自己的价格/SKU/等

这就是我目前设置产品/变体表的方式:

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

我希望上述内容能澄清您的困惑,以及您的问题和疑问的来源

在模式方面,您需要如下内容:


产品
  • #产品标识
  • 名字
  • 描述
(可选)还可以添加:

  • 价格
  • 库存
这是一个与营销相关的表。没有别的了。如果市场营销之外的任何东西在你的应用程序中使用某个产品,那么你最终将陷入一个痛苦的世界

价格(如果存在)是在SKU中为空时用于填充字段的主价格。这使得价格输入更加方便用户

in_stock是一个有希望的自我解释标志,理想情况下由触发器保持。如果与该产品相关的任何SKU有库存,则应为真


产品属性
  • 产品标识
  • #属性标识
  • 名字
产品属性值
  • 属性标识
  • #值\u id
  • 价值观
它只包含颜色、大小等内容,以及蓝色、红色、S、M、L等值

注意product_id字段:为每个产品创建一组新的属性和值。尺寸因产品而异。有时是,M,L,等等。;其他时候是38,40,42,等等。有时候,大小就足够了;其他时候,你需要宽度和长度。蓝色可能是本产品的有效颜色;另一种可能会提供海军蓝、皇家蓝、青色等等。不要假设一种产品的属性与另一种产品的属性之间存在任何关系;当这些相似性存在时,它们完全是装饰性的和巧合的


库存单位
  • 产品标识
  • #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);