MySQL表设计:每一种商品有不确定个数的属性
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表设计:每一种商品有不确定个数的属性的更多相关文章
- mysql表设计注意点
[原创]面试官:讲讲mysql表设计要注意啥 需要设计一个主键 因为你不设主键的情况下,innodb也会帮你生成一个隐藏列,作为自增主键.所以啦,反正都要生成一个主键,那你还不如自己指定一个主键,在有 ...
- 面试mysql表设计要注意啥
面试官:讲讲mysql表设计要注意啥? 引言 大家应该知道烟哥最近要(tiao 咳咳咳),嗯,不可描述! 随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且 ...
- mysql表设计原则
0.三大范式及反范式 ◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列. ◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键:二是没有包含在主键中的 ...
- 【原创】面试官:讲讲mysql表设计要注意啥
引言 近期由于复习了一下mysql的内容,有些心得.随手讲其中一部分知识,都是一些烟哥自己平时工作的总结以及经验.大家看完,其实能避开很多坑.而且很多问题,都是面试中实打实会问到的! 比如 OK,具体 ...
- <转载>面试官: 讲讲MySql表设计需要注意什么?
作者:孤独烟 出处: http://rjzheng.cnblogs.com/ 综述 近期由于复习了一下MySQL的内容看到一篇比较好的文章,转载分享一下.大家看完,其实能避开很多坑.而且很多问题,都是 ...
- mysql表设计
model表 记录网站模块:如视频,音频,调查,01发布内容时.可以指定发布到哪个模块下02可以统计每个模块的访问量设计表注意点01主键不要用id (全部使用 当前表名+id 如modelid)02n ...
- mysql表备份的一种方式
前提: 最近测试环境shop表经常出现表损坏不能正常查询,通过mysql的修复方法,暂时有效.故做该表的迁移操作. 思路是: 停止数据库的操作 1.备份老表. 2.创建一个结构一样的表. 3.将老表 ...
- 【MySQL】MySQL表设计的常用数据类型
整数类型,tinyint.smallint.mediumint.int.bigint 如果需要保存整数(不含小数),可以选择tinyint.smallint.mediumint.int.bigint, ...
- 实现类似微信聊天功能的mysql表设计
前言: 最近设计了一套聊天功能,此功能支持人对人聊天.发送图片.查看聊天记录.按时间展示聊天列表.最后一条聊天数据及未读消息数 下面分享一下表结构及实现逻辑: 表结构: 1.聊天主表 id(主键id) ...
随机推荐
- 效应量Effect Size
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...
- JS笔记加强版3
JS 面向对象及组件开发 JS的面向对象: 1.什么是面向对象编程 用对象的思想去写代码,就是面向对象编程 过程式写法 面向对象写法 我们一直都在使用对象 数组 Array 时间 Date ...
- 搭建简单的node+express+mongodb项目
安装 首先要确保已经安装了 Node.js,接下来创建一个目录,然后进入此目录并将其作为当前工作目录. mkdir myapp cd myapp 通过 npm init 命令为应用创建一个 packa ...
- LintCode 402: Continuous Subarray Sum
LintCode 402: Continuous Subarray Sum 题目描述 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的下标 ...
- 【BZOJ】4555: [Tjoi2016&Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT
[题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016& ...
- 【BZOJ】1040: [ZJOI2008]骑士 环套树DP
[题意]给定n个人的ai和bi,表示第i个人能力值为ai且不能和bi同时选择,求能力值和最大的选择方案.n<=10^6. [算法]环套树DP(基环树) [题解]n个点n条边——基环森林(若干环套 ...
- 【leetcode 简单】第二十三题 二叉树的最大深度
给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15,7], ...
- NYOJ 257 郁闷的C小加(一) (字符串处理)
题目链接 描述 我们熟悉的表达式如a+b.a+b(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符 ...
- NYOJ 138 找球号(二) (哈希)
题目链接 描述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是&qu ...
- 游戏的物理和数学:Unity中的弹道和移动目标提前量计算
下载地址:https://www.jianguoyun.com/p/DZPN6ocQ2siRBhihnx8 弹道计算是游戏里常见的问题,其中关于击中移动目标的自动计算提前量的话题,看似简单,其实还是挺 ...