【JavaWeb】Day41.MySQL概述——多表设计(案例)

一对一

一对一关系表通常是用来做单表的拆分,也就是将一张大表拆分成两张小表,将大表中的一些基础字段放在一张表当中,将其他的字段放在另外一张表当中,以此来提高数据的操作效率。

一对一的应用场景: 用户表(基本信息+身份信息)

基本信息:用户的ID、姓名、性别、手机号、学历

身份信息:民族、生日、身份证号、身份证签发机关,身份证的有效期(开始时间、结束时间)

如果在业务系统当中,对用户的基本信息查询频率特别的高,但是对于用户的身份信息查询频率很低,此时出于提高查询效率的考虑,我就可以将这张大表拆分成两张小表,第一张表存放的是用户的基本信息,而第二张表存放的就是用户的身份信息。他们两者之间一对一的关系,一个用户只能对应一个身份证,而一个身份证也只能关联一个用户。

那么在数据库层面怎么去体现上述两者之间是一对一的关系呢?

其实一对一我们可以看成一种特殊的一对多。同样我们也可以通过外键来体现一对一之间的关系,我们只需要在任意一方来添加一个外键就可以了。

一对一 :在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

多对多

多对多的关系在开发中属于也比较常见的。比如:学生和老师的关系,一个学生可以有多个授课老师,一个授课老师也可以有多个学生。在比如:学生和课程的关系,一个学生可以选修多门课程,一个课程也可以供多个学生选修。

案例:学生与课程的关系

  • 关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择

  • 实现关系:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

案例

下面通过一个综合案例加深对于多表关系的理解,并掌握多表设计的流程。

需求:

1.页面原型-分类管理

分类的信息:分类名称、分类类型[菜品/套餐]、分类排序、分类状态[禁用/启用]、分类的操作时间(修改时间)。

2.页面原型-菜品管理

菜品的信息:菜品名称、菜品图片、菜品分类、菜品售价、菜品售卖状态、菜品的操作时间(修改时间)。

3.页面原型-套餐管理

套餐的信息:套餐名称、套餐图片、套餐分类、套餐价格、套餐售卖状态、套餐的操作时间。

分析

  • 分析分类与菜品之间是什么关系?

一对多关系。一个分类下会有多个菜品,而一个菜品只能归属一个分类。

设计表原则:在多的一方,添加字段,关联属于一这方的主键。

  • 分析套餐与菜品之间是什么关系?

多对多关系。一个套餐下会有多个菜品,而一个菜品也可以出现在多个套餐中。

设计表原则:创建第三张中间表,建立两个字段分别关联菜品表的主键和套餐表的主键。

  • 分析分类和菜品之间的关系?

一对多的关系。已分类下有多个不同套餐,而一个套餐只能属于一个分类。

设计表原则:在多的一方,添加字段,关联属于一这方的主键。

分析页面原型及需求文档后,我们获得:

  • 分类表
  • 业务字段:分类名称、分类类型、分类排序、分类状态

  • 基础字段:id(主键)、分类的创建时间、分类的修改时间

  • 菜品表
  • 业务字段:菜品名称、菜品图片、菜品分类、菜品售价、菜品售卖状态

  • 基础字段:id(主键)、分类的创建时间、分类的修改时间

  • 套餐表
  • 业务字段:套餐名称、套餐图片、套餐分类、套餐价格、套餐售卖状态

  • 基础字段:id(主键)、分类的创建时间、分类的修改时间

表结构之间的关系:

  • 分类表 - 菜品表 : 一对多
  • 在菜品表中添加字段(菜品分类),关联分类表
  • 菜品表 - 套餐表 : 多对多
  • 创建第三张中间表(套餐菜品关联表),在中间表上添加两个字段(菜品id、套餐id),分别关联菜品表和分类表

表结构

分类表:category

  • 业务字段:分类名称、分类类型、分类排序、分类状态

  • 基础字段:id(主键)、创建时间、修改时间

-- 分类表
create table category
(
    id          int unsigned primary key auto_increment comment '主键ID',
    name        varchar(20)      not null unique comment '分类名称',
    type        tinyint unsigned not null comment '类型 1 菜品分类 2 套餐分类',
    sort        tinyint unsigned not null comment '顺序',
    status      tinyint unsigned not null default 0 comment '状态 0 禁用,1 启用',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '更新时间'
) comment '菜品及套餐分类';

菜品表:dish

  • 业务字段:菜品名称、菜品图片、菜品分类、菜品售价、菜品售卖状态

  • 基础字段:id(主键)、分类的创建时间、分类的修改时间

~~~mysql
-- 菜品表
create table dish
(
    id          int unsigned primary key auto_increment comment '主键ID',
    name        varchar(20)      not null unique comment '菜品名称',
    category_id int unsigned     not null comment '菜品分类ID',   -- 逻辑外键
    price       decimal(8, 2)    not null comment '菜品价格',
    image       varchar(300)     not null comment '菜品图片',
    description varchar(200) comment '描述信息',
    status      tinyint unsigned not null default 0 comment '状态, 0 停售 1 起售',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '更新时间'
) comment '菜品';
~~~

套餐表:setmeal

  • 业务字段:套餐名称、套餐图片、套餐分类、套餐价格、套餐售卖状态

  • 基础字段:id(主键)、分类的创建时间、分类的修改时间

~~~mysql
-- 套餐表
create table setmeal
(
    id          int unsigned primary key auto_increment comment '主键ID',
    name        varchar(20)      not null unique comment '套餐名称',
    category_id int unsigned     not null comment '分类id',       -- 逻辑外键
    price       decimal(8, 2)    not null comment '套餐价格',
    image       varchar(300)     not null comment '图片',
    description varchar(200) comment '描述信息',
    status      tinyint unsigned not null default 0 comment '状态 0:停用 1:启用',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '更新时间'
) comment '套餐';
~~~

套餐菜品关联表:setmeal_dish

~~~mysql
-- 套餐菜品关联表
create table setmeal_dish
(
    id         int unsigned primary key auto_increment comment '主键ID',
    setmeal_id int unsigned     not null comment '套餐id ',    -- 逻辑外键
    dish_id    int unsigned     not null comment '菜品id',     -- 逻辑外键
    copies     tinyint unsigned not null comment '份数'
) comment '套餐菜品关联表';
~~~
相关推荐
阿华的代码王国14 分钟前
MySQL ------- 索引(B树B+树)
数据库·mysql
Hello.Reader42 分钟前
StarRocks实时分析数据库的基础与应用
大数据·数据库
执键行天涯44 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
liupenglove1 小时前
golang操作mysql利器-gorm
mysql·golang
yanglamei19621 小时前
基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
前端·数据库·flask
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
工作中的程序员1 小时前
ES 索引或索引模板
大数据·数据库·elasticsearch
严格格1 小时前
三范式,面试重点
数据库·面试·职场和发展
微刻时光2 小时前
Redis集群知识及实战
数据库·redis·笔记·学习·程序人生·缓存
单字叶2 小时前
MySQL数据库
数据库·mysql