数据库(五):多表设计和多表查询

news2024/9/23 21:22:46

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系,基本上分为三种:一对一多对一一对多

一、多表设计

(一)一对多表

需求:根据页面原型及需求文档,完成部门及员工模块的表结构设计。(一个部门对应多个员工)
设计部门表和员工表(父表和子表)

create table tb_emp (
                        id int unsigned primary key auto_increment comment 'ID',
                        username varchar(20) not null unique comment '用户名',
                        password varchar(32) default '123456' comment '密码',
                        name varchar(10) not null comment '姓名',
                        gender tinyint unsigned not null comment '性别, 说明: 1, 2 女',
                        image varchar(300) comment '图像',
                        job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管',
                        entrydate date comment '入职时间',
                        dept_id int unsigned comment '归属部门的id',
                        create_time datetime not null comment '创建时间',
                        update_time datetime not null comment '修改时间'
) comment '员工表';

create table tb_dept(
    id int unsigned primary key auto_increment comment 'ID',
    name varchar(10) not null unique comment '部门名称',
    create_date datetime not null comment '创建时间',
    update_time datetime not null comment  '修改时间'
)comment '部门表';

插入数据:

insert into tb_dept (id, name, create_date, update_time) values
                                                             (1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()),
                                                             (4,'就业部',now(),now()),(5,'人事部',now(),now());

INSERT INTO tb_emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
                                                                                                    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
                                                                                                    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
                                                                                                    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
                                                                                                    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
                                                                                                    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
                                                                                                    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
                                                                                                    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
                                                                                                    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
                                                                                                    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
                                                                                                    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
                                                                                                    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',1,'2007-02-01',1,now(),now()),
                                                                                                    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',1,'2008-08-18',1,now(),now()),
                                                                                                    (13,'fangdongbai','123456','方东白',1,'13.jpg',2,'2012-11-01',2,now(),now()),
                                                                                                    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
                                                                                                    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
                                                                                                    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
                                                                                                    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());

问题:部门数据可以直接删除,然而还有员工归属于该部门下,此时就出现了数据的不完整不一致的问题。
原因:此时这两张表在数据库层面并没有建立关联,所以无法保证数据的一致性和完整性。
解决方案:使用外键约束

(二)物理外键

外键约束(物理外键):使用foreign key定义外键关联另一张表
缺点:影响增删改的效率,仅用于单节点数据库,不适用于分布式、集群场景,容易引发数据库的死锁问题。

在这里插入图片描述
图形化界面的方式:
在这里插入图片描述

(三)逻辑外键

在业务逻辑层,解决外键关联,通过逻辑外键可以很方便的解决物理外键的问题。

(四)一对一

一对一关系多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率。
实现:在任意一方加入外键,关联另一方的主键,并且设置外键为唯一的(UNIQUE)

(五)多对多

实例:一个学生可以选择多门课,一门课也可以供多个学生选择。
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键。

二、多表查询

从多张表中查询数据,并且根据业务需要消除无效信息。
建表:

create table tb_emp (
                        id int unsigned primary key auto_increment comment 'ID',
                        username varchar(20) not null unique comment '用户名',
                        password varchar(32) default '123456' comment '密码',
                        name varchar(10) not null comment '姓名',
                        gender tinyint unsigned not null comment '性别, 说明: 1, 2 女',
                        image varchar(300) comment '图像',
                        job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管',
                        entrydate date comment '入职时间',
                        dept_id int unsigned comment '归属部门的id',
                        create_time datetime not null comment '创建时间',
                        update_time datetime not null comment '修改时间'
) comment '员工表';

create table tb_dept(
    id int unsigned primary key auto_increment comment 'ID',
    name varchar(10) not null unique comment '部门名称',
    create_date datetime not null comment '创建时间',
    update_time datetime not null comment  '修改时间'
)comment '部门表';

insert into tb_dept (id, name, create_date, update_time) values
                                                             (1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()),
                                                             (4,'就业部',now(),now()),(5,'人事部',now(),now());

INSERT INTO tb_emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
                                                                                                    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
                                                                                                    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
                                                                                                    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
                                                                                                    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
                                                                                                    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
                                                                                                    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
                                                                                                    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
                                                                                                    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
                                                                                                    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
                                                                                                    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
                                                                                                    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',1,'2007-02-01',1,now(),now()),
                                                                                                    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',1,'2008-08-18',1,now(),now()),
                                                                                                    (13,'fangdongbai','123456','方东白',1,'13.jpg',2,'2012-11-01',2,now(),now()),
                                                                                                    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
                                                                                                    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
                                                                                                    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
                                                                                                    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());

查询:
通过这种查询,会造成不正常的链接,也就是笛卡尔积
在这里插入图片描述
消除了无效的笛卡尔积:
在这里插入图片描述

(一)内连接

相当于查询A、B交集部分的数据。
在这里插入图片描述

# 查询员工的姓名,及所属的部门名称(隐式内连接)
select tb_emp.name,tb_dept.name from tb_emp,tb_dept where tb_emp.dept_id=tb_dept.id;
#查询员工姓名及所属部门名称(显示内连接)
select tb_emp.name,tb_dept.name from tb_emp inner join tb_dept on dept_id=tb_dept.id;

(二)外连接

左外连接,查询左表所有数据(包含两张表交集部分的数据);右外连接,查询右表所有数据(包含两张表交集部分的数据)。
在这里插入图片描述

#查询 所有员工的姓名,及所属的部门名称(左外连接)
select * from tb_emp e left join tb_dept d on e.dept_id=d.id;
#查询部门表 所有 部门的名称,和对应的员工名称(右外连接)
select e.name,d.name from tb_emp e right join tb_dept d on e.dept_id=d.id;

(三)子查询

在这里插入图片描述
在这里插入图片描述

1、标量子查询

子查询返回的是单个值(数值、字符串、日期等),最简单的形式。常用的操作符是:= <> > >= <= <

#子查询
#标量子查询
#A——查询“教研部”的所有员工信息 查教研部ID+查询部门ID下的员工信息
select tb_dept.id from tb_dept where name='教研部';
select * from tb_emp where id = 2;
# 合并
select * from tb_emp where dept_id =(select tb_dept.id from tb_dept where name='教研部');

# 在方东白入职之后的员工信息 入职时间+该时间之后的员工信息
select entrydate from tb_emp where name='方东白';

select * from tb_emp where entrydate>='2012-11-01';
# 合并
select * from tb_emp where entrydate>=(select entrydate from tb_emp where name='方东白');

2、列子查询

子查询返回的结果是一列(可以是多行),常用的操作符in 、not in等。

#列子查询
#查询 教研部 和 咨询部 的所有员工信息 查询ID+查询该部门下的员工信息
select tb_dept.id from tb_dept where name='教研部' or name = '咨询部';

select * from tb_emp where dept_id in (2,3);
# 合并
select * from tb_emp where dept_id in (select tb_dept.id from tb_dept where name='教研部' or name = '咨询部');

3、行子查询

子查询返回的结果是一行(可以是多列),常用的操作符:= 、<>、 in 、not in

#行子查询
#查询与“韦一笑”这个员工的 入职日期 和 职位 都相同你的员工 =查询“韦一笑”的 入职日期 和职位 + 查询和他入职日期和职位都相同的人
select entrydate,job from tb_emp where name='韦一笑';
select * from tb_emp where entrydate = '2007-01-01' and job = 2;
#合并
select * from tb_emp where entrydate = (select entrydate from tb_emp where name='韦一笑') and job = (select job from tb_emp where name='韦一笑');
#优化
select * from tb_emp where (entrydate,job)= ('2007-01-01' ,job = 2);
select * from tb_emp where (entrydate,job)= (select entrydate,job from tb_emp where name='韦一笑');

4、表子查询

子查询返回的是多行多列,常作为临时表,常用的操作符in

#表子查询
#查询入职日期是“2006-01-01”之后的员工信息,及其部门信息
#先查询“2006-01-01”之后的员工信息
#在查询部门信息
select * from tb_emp where entrydate>'2006-01-01';
select  e.*,d.name from (select * from tb_emp where entrydate>'2006-01-01') e,tb_dept d where e.dept_id =d.id;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2053823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在寂静中用电脑找回失踪的手机?远程控制了解一下

经过一番努力&#xff0c;我终于成功地将孩子哄睡了。夜深人静&#xff0c;好不容易有了一点自己的时间&#xff0c;就想刷手机放松放松&#xff0c;顺便看看有没有重要信息。但刚才专心哄孩子去了&#xff0c;一时就忘记哄孩子之前&#xff0c;顺手把手机放哪里去了。 但找过手…

进程相关知识

进程和程序的区别 程序 程序是静态的&#xff0c;是存储在硬盘、SSD等存储介质中的一个文件&#xff0c;通常由源代码&#xff08;如 .c 文件&#xff09;编译生成的二进制可执行文件&#xff08;如 a.out&#xff09;。程序包含了指令和数据&#xff0c;但在未被执行时&#…

【计算机操作系统】基本分页存储管理

文章目录 基本分页存储管理分页存储的概念重要的数据结构——页表页表项大小计算地址转换实现 基本地址变换机构具有快表的地址变换机构快表&#xff08;TLB&#xff09;的概念引入快表后的地址变换局部性原理 两级页表单级页表 vs 两级页表 基本分页存储管理 非连续分配&#…

使用Python编写AI程序,让机器变得更智能

人工智能&#xff08;AI&#xff09;是当今科技领域最热门的话题之一。随着Python编程语言的逐渐流行&#xff0c;它已经成为许多人工智能编程的首选语言。本文将介绍如何使用Python编写AI程序&#xff0c;让机器变得更智能。 首先&#xff0c;Python提供了大量的AI库和工具&a…

Easysearch 性能测试方法概要

&#xff08;公众号用的是QQ音乐&#xff0c;可以随时听&#xff09; INFINI Easysearch INFINI Easysearch 是一个分布式的近实时搜索与分析引擎&#xff0c;核心引擎基于开源的 Apache Lucene。Easysearch 衍生自基于开源协议Apache 2.0 的Elasticsearch 7.10 版本&#xff0…

4-1-2 直流电机(电机专项教程)

4-1-2 直流电机&#xff08;电机专项教程&#xff09; 4-1-2 直流电机主要参数尺寸参数额定电压额定电流空载转速 如何控制直流电机有刷直流电机转向控制H桥电路控制转向 如何控制电机转速PWM控制电机转速 4-1-2 直流电机 之前学习了有刷直流电机的基本结构个工作原理&#xff…

[数据集][图像分类]电力场景电力线固定处连接处腐蚀有鸟巢分类数据集1279张3类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1279 分类类别数&#xff1a;3 类别名称:["corrosion","nes…

SparkSQL遵循ANSI标准

ANSI简介 ANSI Compliance通常指的是遵循美国国家标准学会&#xff08;American National Standards Institute, ANSI&#xff09;制定的标准。在计算机科学和技术领域&#xff0c;这通常涉及到数据库管理系统&#xff08;DBMS&#xff09;对于SQL语言的支持程度。 ANSI为SQL…

FreeRTOS 快速入门(二)之内存管理

目录 一、概述二、FreeRTOS 中管理内存的 5 种方法1、Heap_12、Heap_23、Heap_34、Heap_44.1 内存申请4.2 内存释放 5、Heap_5 三、Heap 相关的函数1、pvPortMalloc/vPortFree2、xPortGetFreeHeapSize3、xPortGetMinimumEverFreeHeapSize4、malloc 失败的钩子函数 一、概述 在…

CDGA|数据治理,就像在厨房里炒一盘好菜

数据治理&#xff0c;就像在厨房里炒一盘好菜&#xff0c;是一门既讲究技巧又注重细节的艺术。在这个信息爆炸的时代&#xff0c;数据如同食材&#xff0c;是支撑企业决策、优化运营、驱动创新的基石。而数据治理&#xff0c;则是将这些纷繁复杂的数据“食材”精心挑选、清洗、…

使用NPS搭建socks5隧道 | 内网穿透

在看春秋云镜靶场的WP时碰到用NPS来做代理的&#xff0c;这里刚好看到这篇文章&#xff1a;https://www.cnblogs.com/cute-puli/p/15508251.html&#xff0c;学习一下。 GUI界面管理更加方便。 实验环境 网络拓扑&#xff1a; kali&#xff1a; VMnet1&#xff08;公网&…

ORB-SLAM3演示及运行

ORB-SLAM安装完成后的运行案例 ros启动 1、修改双目部分文件&#xff0c;主要是图象订阅话题名称 因为我是用的双目灰度相机&#xff0c;需要修改ORB_SLAM3/Examples/ROS/ORB_SLAM3/src下的 ros_stereo.cc和 ros_stereo_intertial.cc. 把订阅的话题改为自己系统发布的图象…

盲盒小程序开发,创新市场收益渠道

对于年轻消费者来说&#xff0c;盲盒是一个具有超强惊喜感和刺激性的消费方式&#xff0c;盲盒也在各大社交平台迅速火爆&#xff0c;线下门店更是上演“大长龙”式的排队景观&#xff0c;盲盒成为了一个具有非常大发展前景的行业&#xff01; 一、线上发展 盲盒的销售渠道除…

矩阵和神经网络的优雅与力量-《Python神经网络编程》读后感

《Python神经网络编程》是一本非常优秀的神经网络入门编程书&#xff0c;作者手把手从安装环境开始&#xff0c;每一行代码都是在树莓派上就能运行的&#xff0c;甚至可以说不需要什么第三方库&#xff0c;仅仅用了矩阵的优雅和力量&#xff0c;就能够在树莓派上顺利的运行。 …

并发编程 | CountDownLatch是如何控制线程执行流程

CountDownLatch 是 Java 并发编程中的一个同步工具类&#xff0c;这个工具经常用来用来协调多个线程之间的同步&#xff0c;下面我们就来一起认识一下 CountDownLatch。 CountDownLatch介绍 应用场景 CountDownLatch主要是用于让一个或多个线程等待其他线程完成某些操作后再…

鸿蒙Harmony实战开发知识:“UIAbility组件的3种启动模式”

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景&#xff0c;系统提供了三种启动模式&#xff1a; singleton启动模式 singleton启动模式为单实例模式&#xff0c;也是默认情况下的启动模式。 每次调用startAbility()方法时&#xff0c;如…

windows下的redis7.0.11的下载

天&#xff0c;我找redis7.0.11的安装包就找了好久&#xff0c;终于给我找到了。市面上好多是linux版本的。 安装包&#xff1a;Release Redis 7.0.11 for Windows zkteco-home/redis-windows GitHub 解压之后是这样的。 然后你要测试能不能启动&#xff1a; 1、指定配置文…

复现DOM型XSS攻击(1-8关)

目录 第一关&#xff1a;​ 分析代码&#xff1a; 第二关&#xff1a; 分析代码&#xff1a; 第三关&#xff1a; 分析代码&#xff1a; 第四关&#xff1a; 分析代码&#xff1a; 第五关&#xff1a; 分析代码&#xff1a; 第六关&#xff1a; 分析代码&#xff1…

volatitle-线程并发-小白一文速通

目录 简而言之 专业术语解释 1、可见性 原理简介 原理图解 其他方式 2、原子性 原理简介 结合实例分析 3、有序性 原理简介 线程安全问题 Volatile效果 1、保证可见性 2、保证有序性 3、无法保证原子性 Volatile底层的实现机制(重点掌握) 经典案例 Java双重检…

朗致面试----Java开发、Java架构师

一共三轮面试。第一轮是逻辑行测&#xff0c;第二轮是技术面试&#xff08;面试官-刘老师&#xff09;&#xff0c;第三轮是CTO面试&#xff08;面试官-屠老师&#xff09;。第三轮Coding做完之后共享屏幕讲一个你自己负责过的项目&#xff08;请提前准备好架构图&#xff0c;开…