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. Android的静默安装

    原文 Android的静默安装似乎是一个很有趣很诱人的东西,但是,用普通做法,如果手机没有root权限的话,似乎很难实现静默安装,因为Android并不提供显示的Intent调用,一般是通过以下方式安 ...

  2. Linux centos7下设置Tomcat开机自启动

    1,centos7 使用 systemctl 替换了 service命令 参考:redhat文档: https://access.redhat.com/documentation/en-US/Red_ ...

  3. Linux下如何卸载软件(Debian系)

    说明:此方法适用于Debian.Ubuntu等带apt工具的操作系统. 步骤: 1.首先我们需要知道将要卸载的软件名称,比如我现在打算卸载tightvncserver,但是如果你不确定名称,没关系,可 ...

  4. 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$ ...

  5. SSM框架整合遇到的问题

    1.Maven中Dubbo集成spring2.5以上版本 项目中dubbo集成spring4.x,配置pom时需要注意排除spring的依赖,我这里用的是tomcat,所以把jboss也排除了: &l ...

  6. Eng1—English daily notes

    English daily notes 2015年 4月 Phrases As a side note 作为附注,顺便说句题外话,和by the way意思相近,例句 As a side note, ...

  7. 【CODEVS】1922 骑士共存问题

    [算法]二分图最大匹配(最大流) [题解]按(i+j)奇偶性染色后,发现棋子跳到的地方刚好异色. 然后就是二分图了,对于每个奇点向可以跳到的地方连边,偶点不需连(可逆). 所以题目要求转换为求二分图上 ...

  8. 使用infinite-scroll实现Ghost博文列表的滚动加载

    Ghost博客系统默认提供的博文列表为传统的翻页方式(通过点击上一页.下一页等按钮来切换),随着移动客户端的发展,瀑布流式的滚动加载方式得到广泛应用,有效地提高了用户浏览信息的流畅度.下面详述如何通过 ...

  9. CMDB概述(二)

    运维自动化路线: cmdb的开发需要包含三部分功能: ·采集硬件数据  ·API ·页面管理 执行流程:服务器的客户端采集硬件数据,然后将硬件信息发送到API,API负责将获取到的数据保存到数据库中, ...

  10. [\u4e00-\u9fa5] //匹配中文字符

     [\u4e00-\u9fa5] //匹配中文字符 ^[1-9]\d*$    //匹配正整数^[A-Za-z]+$   //匹配由26个英文字母组成的字符串^[A-Z]+$      //匹配由26 ...