I personally would use a model similar to the following:

The product table would be pretty basic, your main product details:

create table product
(
part_number int, (PK)
name varchar(10),
price int
);
insert into product values
(1, 'product1', 50),
(2, 'product2', 95.99);

Second the attribute table to store the each of the different attributes.

create table attribute
(
attributeid int, (PK)
attribute_name varchar(10),
attribute_value varchar(50)
);
insert into attribute values
(1, 'color', 'red'),
(2, 'color', 'blue'),
(3, 'material', 'chrome'),
(4, 'material', 'plastic'),
(5, 'color', 'yellow'),
(6, 'size', 'x-large');

Finally create the product_attribute table as the JOIN table between each product and its attributes associated with it.

create table product_attribute
(
part_number int, (FK)
attributeid int (FK)
);
insert into product_attribute values
(1, 1),
(1, 3),
(2, 6),
(2, 2),
(2, 6);

Depending on how you want to use the data you are looking at two joins:

select *
from product p
left join product_attribute t
on p.part_number = t.part_number
left join attribute a
on t.attributeid = a.attributeid;

See SQL Fiddle with Demo. This returns data in the format:

PART_NUMBER | NAME       | PRICE | ATTRIBUTEID | ATTRIBUTE_NAME | ATTRIBUTE_VALUE
___________________________________________________________________________
1 | product1 | 50 | 1 | color | red
1 | product1 | 50 | 3 | material | chrome
2 | product2 | 96 | 6 | size | x-large
2 | product2 | 96 | 2 | color | blue
2 | product2 | 96 | 6 | size | x-large

But if you want to return the data in a PIVOT format where you have one row with all of the attributes as columns, you can use CASE statements with an aggregate:

SELECT p.part_number,
p.name,
p.price,
MAX(IF(a.ATTRIBUTE_NAME = 'color', a.ATTRIBUTE_VALUE, null)) as color,
MAX(IF(a.ATTRIBUTE_NAME = 'material', a.ATTRIBUTE_VALUE, null)) as material,
MAX(IF(a.ATTRIBUTE_NAME = 'size', a.ATTRIBUTE_VALUE, null)) as size
from product p
left join product_attribute t
on p.part_number = t.part_number
left join attribute a
on t.attributeid = a.attributeid
group by p.part_number, p.name, p.price;

See SQL Fiddle with Demo. Data is returned in the format:

PART_NUMBER | NAME       | PRICE | COLOR | MATERIAL | SIZE
_________________________________________________________________
1 | product1 | 50 | red | chrome | null
2 | product2 | 96 | blue | null | x-large

As you case see the data might be in a better format for you, but if you have an unknown number of attributes, it will easily become untenable due to hard-coding attribute names, so in MySQL you can use prepared statements to create dynamic pivots. Your code would be as follows (See SQL Fiddle With Demo):

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attribute_name = ''',
attribute_name,
''', a.attribute_value, NULL)) AS ',
attribute_name
)
) INTO @sql
FROM attribute; SET @sql = CONCAT('SELECT p.part_number
, p.name
, ', @sql, '
from product p
left join product_attribute t
on p.part_number = t.part_number
left join attribute a
on t.attributeid = a.attributeid
GROUP BY p.part_number
, p.name'); PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

This generates the same result as the second version with no need to hard-code anything. While there are many ways to model this I think this database design is the most flexible.

MySQL表设计:每一种商品有不确定个数的属性的更多相关文章

  1. mysql表设计注意点

    [原创]面试官:讲讲mysql表设计要注意啥 需要设计一个主键 因为你不设主键的情况下,innodb也会帮你生成一个隐藏列,作为自增主键.所以啦,反正都要生成一个主键,那你还不如自己指定一个主键,在有 ...

  2. 面试mysql表设计要注意啥

    面试官:讲讲mysql表设计要注意啥? 引言 大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述! 随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且 ...

  3. mysql表设计原则

    0.三大范式及反范式 ◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列.  ◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键:二是没有包含在主键中的 ...

  4. 【原创】面试官:讲讲mysql表设计要注意啥

    引言 近期由于复习了一下mysql的内容,有些心得.随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且很多问题,都是面试中实打实会问到的! 比如 OK,具体 ...

  5. <转载>面试官: 讲讲MySql表设计需要注意什么?

    作者:孤独烟 出处: http://rjzheng.cnblogs.com/ 综述 近期由于复习了一下MySQL的内容看到一篇比较好的文章,转载分享一下.大家看完,其实能避开很多坑.而且很多问题,都是 ...

  6. mysql表设计

    model表 记录网站模块:如视频,音频,调查,01发布内容时.可以指定发布到哪个模块下02可以统计每个模块的访问量设计表注意点01主键不要用id (全部使用 当前表名+id 如modelid)02n ...

  7. mysql表备份的一种方式

    前提: 最近测试环境shop表经常出现表损坏不能正常查询,通过mysql的修复方法,暂时有效.故做该表的迁移操作. 思路是: 停止数据库的操作 1.备份老表.  2.创建一个结构一样的表. 3.将老表 ...

  8. 【MySQL】MySQL表设计的常用数据类型

    整数类型,tinyint.smallint.mediumint.int.bigint 如果需要保存整数(不含小数),可以选择tinyint.smallint.mediumint.int.bigint, ...

  9. 实现类似微信聊天功能的mysql表设计

    前言: 最近设计了一套聊天功能,此功能支持人对人聊天.发送图片.查看聊天记录.按时间展示聊天列表.最后一条聊天数据及未读消息数 下面分享一下表结构及实现逻辑: 表结构: 1.聊天主表 id(主键id) ...

随机推荐

  1. 「Django」rest_framework学习系列-节流控制

    1.节流自定义类: import time from api import models VISIT_RECORD = {} class VisitThrottle(BaseThrottle): #设 ...

  2. 居中div,居中浮动的元素

    定位法:position:absolute 如果子级div有定义宽和高的话就可以用这个方法.注意:margin-top,和margin-left的值均为高和宽值的一半 margin:auto法 这个也 ...

  3. Drools规则引擎环境搭建

    Drools 是一款基于Java 的开源规则引擎,所以在使用Drools 之前需要在开发机器上安装好JDK 环境,Drools5 要求的JDK 版本要在1.5 或以上. Drools5 提供了一个基于 ...

  4. (转)javap 指令集

    栈和局部变量操作将常量压入栈的指令aconst_null 将null对象引用压入栈iconst_m1 将int类型常量-1压入栈iconst_0 将int类型常量0压入栈iconst_1 将int类型 ...

  5. PL/SQL Developer 中的问题:Initialization error Could not load ".../oci.dll"解决方法

    ---------------------------------------------------------------------------------------------------- ...

  6. Arrays.asList方法遇到的问题

    在使用Arrays.asList(T...a)方法时,遇到了 java.lang.UnsupportedOperationException  异常. 后来发现,该方法返回的类型是Arrays$Arr ...

  7. 算法专题-STL篇

    这篇文章着重记录c++中STL的用法.主要粗略的介绍其用法,以知识点的形式呈现其功能,不会深入源码分析其工作原理. 排序和检索. sort(a,a+n),对a[0]往后的n个元素(包括a[0])进行排 ...

  8. HDU 1211 EXGCD

    EXGCD的模板水题 RSA算法给你两个大素数p,q定义n=pq,F(n)=(p-1)(q-1) 找一个数e 使得(e⊥F(n)) 实际题目会给你e,p,q计算d,$de \mod F(n) = 1$ ...

  9. Spring boot中使用log4j记录日志

    之前在Spring Boot日志管理一文中主要介绍了Spring Boot中默认日志工具(logback)的基本配置内容.对于很多习惯使用log4j的开发者,Spring Boot依然可以很好的支持, ...

  10. Linux下命令lrzsz

    lrzsz是什么 在使用Linux的过程中,难免少不了需要上传下载文件,比如往服务器上传一些war包之类的,之前都是使用winSCP,lrzsz是一个更方便的命令,可以直接在Linux中输入命令,弹出 ...