多表设计-案例
- 参考页面原型及需求,设计合理的表结构
一、需求
1. 资料
- 参考资料中提供的 苍穹外卖_管理后台 页面原型,设计分类管理、菜品管理、套餐管理模块的表结构。
- 资料来自于:微信公众号—>黑马程序员—>百度网盘资料
2. 步骤
- 阅读页面原型及需求文档,分析各个模块涉及到的表结构,及表结构之间的关系。
- 根据页面原型及需求文档,分析各个表结构中具体的字段及约束。
二、关系分析
1. 介绍
-
阅读页面原型及需求文档,分析各个模块涉及到的表结构,及表结构之间的关系。
-
根据需求,我们只需要阅读分类管理、菜品管理、套餐管理模块的页面原型与需求文档
2. 分析
(1) 菜品&分类
- 菜品 与 分类 的关系:一对多(1:n)
- 一个菜品只能归属一个分类,而一个分类有很多菜品
- 由于 菜品 与 分类 是 一对多 的关系:
- 所以在 多的一方:菜品表中增加一个外键字段 category_id(分类ID),用于关联另一方的 主键ID
(2) 套餐&分类
- 套餐 与 分类 的关系:一对多(1:n)
- 一个套餐只能归属一个分类,而一个分类有很多套餐
- 由于 套餐 与 分类 是 一对多 的关系:
- 所以在 多的一方:套餐表中增加一个外键字段 category_id(分类ID),用于关联另一方的 主键ID
(3) 套餐&菜品
- 套餐 与 菜品 的关系:一对多(n:n)
- 一个套餐中可以包装多个菜品,而一个菜品可以属于多个套餐
- 由于 套餐 与 菜品 是 多对多 的关系:
- 所以,需要建立一张中间表:套餐菜品中间表,设置两个外键,分别关联两方的主键
三、表结构
- 根据页面原型及需求文档,分析各个表结构中具体的字段及约束。
1. 分类表
(1) 字段需求
(2) 建表
-
SQL操作
-- 多表设计-案例 # 1. 分类表 category create table category( -- 基础字段主键ID: int类型,无符号,主键,自增 id int unsigned primary key auto_increment comment '主键ID', -- 分类名称: 字符串,使用varchar类型,长度2-20位,变向说明不能为空,需求中没有说明唯一性(需要跟产品经理沟通确认) name varchar(20) not null unique comment '分类名称', -- 分类类型: 1-2范围小,使用tinyint类型(1-菜品分类,2-套餐分类),无符号,菜品分类必填非空 type tinyint unsigned not null comment '分类类型,说明:1-菜品分类,2-套餐分类', -- 排序: 0-99范围小,使用tinyint类型,无符号,非空 sort tinyint unsigned not null comment '排序', -- 状态: 0-1范围小,使用tinyint类型(0-停用,1-启用),无符号,状态默认为停用,因此是非空 status tinyint unsigned not null default '0' comment '状态,说明:0-停用,1-启用', -- 基础字段创建时间、修改时间,日期时间类型,非空 create_time datetime not null comment '创建时间', update_time datetime not null comment '修改时间' ) comment '分类表';
-
图形化操作
2. 菜品表
(1) 字段需求
- 暂时不考虑口味字段:
(2) 建表
-
SQL操作
# 2. 菜品表 dish create table dish( -- 基础字段:ID,int类型,无符号,主键,自增 id int unsigned primary key auto_increment comment '主键ID', -- 菜品名称:字符串,使用varchar类型(长度2-20位),必填非空,唯一 name varchar(20) not null unique comment '菜品名称', -- 菜品分类ID:使用逻辑外键,int类型,非空 category_id int unsigned not null comment '分类ID', -- 价格:decimal类型(长度1-8,2位小数),必填非空 price decimal(8,2) not null comment '价格', -- 图像:图片url地址属于字符串,使用varchar类,必填非空 image varchar(300) not null comment '图像', -- 菜品描述:字符串,使用varchar类型 description varchar(200) comment '菜品描述', -- 售卖状态:0-1范围小,使用tinyint类型(0-停售,1-启售),无符号,非空,默认停售 status tinyint unsigned not null default '0' comment '售卖状态,说明:0-停售,1-启售', -- 基础字段:创建时间、修改时间 create_time datetime not null comment '创建时间', update_time datetime not null comment '修改时间' ) comment '菜品表';
-
图形化操作
3. 套餐表
(1) 字段需求
(2) 建表
-
SQL操作
# 3. 套餐表 setmeal create table setmeal( -- 基础字段:主键ID:int类型,无符号,主键,自增 id int unsigned primary key auto_increment comment '主键ID', -- 套餐名称:字符串,使用varchar(长度2-20位),非空,唯一 name varchar(20) not null unique comment '套餐名称', -- 套餐分类ID:使用逻辑外键,int类型,无符号,非空 category_id int unsigned not null comment '分类ID', -- 价格:decimal(长度1-8, 2位小数),非空 price decimal(8,2) not null comment '价格', -- 图片:图片url地址属于字符串,使用varchar类,非空 image varchar(300) not null comment '图片', -- 套餐描述:字符串,使用varchar类型 description varchar(200) comment '套餐描述', -- 售卖状态:0-1范围小,使用tinyint类型(0-停售,1-启售),无符号,非空,默认停售 status tinyint unsigned not null default '0' comment '售卖状态,说明:0-停售,1-启售', -- 基础字段:创建时间、修改时间 create_time datetime not null comment '创建时间', update_time datetime not null comment '修改时间' ) comment '套餐表';
-
图形化操作
- 注意:套餐菜品字段是放在中间表的
4. 套餐菜品中间表
(1) 字段需求
(2) 建表
-
SQL操作
# 4. 套餐菜品关系表 setmeal_dish create table setmeal_dish( -- 基础字段:主键ID,int类型,无符号,主键,自增 id int unsigned primary key auto_increment comment '主键ID', -- 套餐ID:逻辑外键,关联套餐表的主键ID setmeal_id int unsigned not null comment '套餐ID', -- 菜品ID:逻辑外键,关联菜品表的主键ID dish_id int unsigned not null comment '菜品ID', -- 菜品份数: copies tinyint unsigned not null comment '菜品份数' ) comment '套餐菜品关系表';
-
图形化操作
(3) 注意事项
-
关系表 不属于 业务表,因此不需要增加 创建时间 与 修改时间 这两个字段。
四、总结
1. 关系
①. 一对一
- 任意一方,添加外键,关联另外一方的主键。
②. 一对多
- 在多的一方添加外键,并且设置唯一性,关联另外一方的主键。
③. 多对多
- 通过中间表来维护,中间表的两个外键,分别关联另外两张表的主键。
-
分类表 与 菜品表:一对多
-
分类表 与 套餐表:一对多
-
套餐表 与 菜品表:多对多
2. 多表设计流程
-
①. 阅读页面原型及需求文档,分析各个模块涉及到的表结构,及表结构之间的关系。
-
②. 根据页面原型及需求文档,分析各个表结构中具体的字段及约束。