开开心心带你学习MySQL数据库之第七篇

news2024/11/25 12:52:12

previewfile_2967697841

MySQL提供的约束
1.not null
2.unique
3.default
4.primary key
5.foreign key

表的设计

  1. 找到实体
  2. 确定实体间的关系
    • 一对一
    • 一对多
    • 多对多

聚合查询
~~行之间的运算
~~聚合函数
~~分组group by

联合查询

~~多表查询
~~笛卡尔积: 把两个表放到一起进行排列组合

班级表

classIdclassName
11班
22班

学生表

studentIdnameclassId
1张三1
2李四1
3王五2
4赵六2

学生表和班级表的笛卡尔积结果

studentIdnameclassIdclassIdclassName
1张三111班
1张三122班
2李四111班
2李四122班
3王五211班
3王五222班
4赵六211班
4赵六222班

笛卡尔积是得到了一张更大的表
笛卡尔积的列数是两个表列数之和
行数是两个表行数之积

由于笛卡尔积是排列组合出来的结果.这里的有些数据是无效/无意义的数据.

image-20230909004649269

当去掉无效数据之后,笛卡尔积里剩余的数据就是当前每个同学在哪个班级里这样的信息了

studentIdnameclassIdclassIdclassName
1张三111班
2李四111班
3王五222班
4赵六222班

像"两个classld对得上"在SQL中就可以使用一个 where子句的条件来描述
基于笛卡尔积+条件进行查询,此时就是联合查询/多表查询

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

create table classes(
    id int primary key auto_increment, 
    name varchar(20), 
   `desc` varchar(100)
);
create table student(
    id int primary key auto_increment,
    sn varchar(20), 
    name varchar(20),
    qq_mail varchar(20), 
    classes_id int
);
create table course(
    id int primary key auto_increment, 
    name varchar(20)
);
create table score(
    score decimal(3,1), 
    student_id int, course_id int
);

insert into classes(name, `desc`) values  
	('计算机系2019级1班 ', '学习了计算机原理、C和Java语言、数据结构和算法 '), 	         ('中文系2019级3班 ','学习了中国传统文学 '), 
    ('自动化2019级5班 ','学习了机械自动化 ');
    
insert into student(sn, name, qq_mail, classes_id) values 
    ('09982','黑旋风李逵 ','xuanfeng@qq.com',1), 
    ('00835','菩提老祖 ',null,1), 
    ('00391','白素贞',null,1), 
    ('00031','许仙 ','xuxian@qq.com',1), 
    ('00054','不想毕业 ',null,1), 
    ('51234','好好说话 ','say@qq.com',2), 
    ('83223','tellme',null,2),
    ('09527','老外学中文 ','foreigner@qq.com',2); 
    
insert into course(name) values 
    ('Java'),('中国传统文化 '),('计算机原理 '),('语文 '),('高阶数学 '),('英文 '); 
    
insert into score(score, student_id, course_id) values 
-- 黑旋风李逵 
	(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6), 
-- 菩提老祖 
    (60, 2, 1),(59.5, 2, 5), 
-- 白素贞 
    (33, 3, 1),(68, 3, 3),(99, 3, 5), 
-- 许仙 
    (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6), 
-- 不想毕业 
    (81, 5, 1),(37, 5, 5), 
-- 好好说话 
    (56, 6, 2),(43, 6, 4),(79, 6, 6), 
-- tellme 
    (80, 7, 2),(92, 7, 6); 

image-20230909095954018

(1)查询‘’许仙‘’同学的成绩
“许仙” => student表
成绩 => score表
~~要找的两个关键信息,存在于不同的表中,就需要进行联合查询
1)先把student表和score表笛卡尔积 => select * from student, score;
2)去掉无效数据 => select * from student, score where id = student_id;
3)按照“许仙‘’名字来筛选 => select * from student, score where id = student_id and student.name = '许仙';

image-20230909102622273

当前结果的行数已经是所求了.还需要针对列数也精简一下~~
select student.name, score.score from student, score where id = student_id and student.name = '许仙';
image-20230909103039670

如果列名重名怎么办?
通过表名.列名的方式来指定列
⭐️⭐️⭐️建议大家,多表查询的时候,显式的把表名给写出来
select * from student, score where student.id = score.student_id;

多表查询一般实现步骤:
1.分析清楚需求中,涉及到的信息都在哪些表里
2.针对这多个表进行笛卡尔积.
3.筛选出其中的有效数据(此处使用学生 id作为关联条件)
4.结合需求中的条件,进一步加强条件
5.针对列进行精简

多表查询查询‘’许仙‘’同学成绩的另一种写法
1)完成笛卡尔积 => select * from student join score;
2)此时,后续条件不是使用where关键字了,而是使用on
~~select * from student join score on student.id = score.student_id;
3)按照名字来筛选select * from student join score on student.id = score.student_id and student.name = '许仙';
4)精简列 select student.name, score.score from student join score on student.id = score.student_id and student.name = '许仙';
image-20230909105339762

使用join on的方式和第一种方式,效果是相同的

(2)查询所有同学的总成绩,及同学的个人信息
总成绩 => 分数表/score表
个人信息 => 学生表/student表
此时需要按照学生姓名/学号进行分组(group by)再针对每个组,分别求和

select 
	student.name, 
	sum(score.score) 
from 
	student, 
	score where student.id = score.student_id 
group by 
	id;

image-20230909114624852

联合查询,在学校上数据库课考试的时候,一定是最后的一个大题
实际开发中,慎重使用联合查询~~联合查询,本质上是"笛卡尔积"笛卡尔积,就把多个表排列组合…
如果表里的数据多,此时笛卡尔积开销是非常大的!!

(3)查询所有同学的成绩,课程名字,及同学名字
学生名字 => student表
课程名字 => course表
分数 => score表 => student 和 course表的关联表
三张表,就得指定两个连接条件

select 
	student.name, 
	course.name, 
	score.score 
from 
	student, 
	course, score 
where 
	student.id = score.student_id 
and 
	course.id = score.course_id;

绝大多数的面试题,其实都是清楚明确的,并不是死记硬背的
二叉搜索树查询的时间复杂度 => O(N)
哈希表查询的时间复杂度 => O(1)
默认是最坏,不是平均!!!单叉树,相当于链表了,
得是一个平衡的二叉搜索树,才能达到 logN~~TreeMap里面是红黑树

面试中一个最重要的原则,实事求是!!!
遇到不会千万不要瞎编,面试官阅人无数~~人家很容易能识别你是不是在编~被戳穿了,妥妥的小丑!!!


外连接

上述联合查询,其实都是"内连接"(inner join)
mysql还有一种联合查询,叫做外连接,
内连接和外连接都是进行笛卡尔积.但是细节上有所差别

create table student(
	id int,
	name varchar(20)
);
create table score(
    student_id int, 
    score int
);
insert into student values
	(1, '张三'),
	(2, '李四'),
	(3, '王五');
insert into score values
	(1, 90),
	(2, 80),
	(3, 70);

当前情况下,这两个表的数据是一 一对应的(第一个表的每个记录,在第二个表里都有体现.第二个表的每个记录,在第一个表里也都有体现)此时内连接和外连接,查询结果是相同的
内连接

select 
	name, 
	score 
from 
	student join score 
on 
	student.id = score.student_id;

外连接分为左外连接和右外连接,如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完
全显示我们就说是右外连接
左外连接

-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;

select 
	name, 
	score 
from 
	student left join score 
on 
	student.id = score.student_id;

右外连接

-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

select 
	name, score 
from 
	student right join score 
on 
	student.id = score.student_id;

如果两个表中数据不再一一对应了,此时进行内连接,结果就只是两个表中都有体现的数据
如果进行左外连接,就是以左侧的表为准.左侧表中的所有数据都能体现出来
如果进行右外连接,就是以右侧表为准.右侧表中的所有数据都体现出来

image-20230909151820417

相比之下,内连接的使用是更多一些.外连接主要是一些特定场景
三张表联合查询怎么外连接查询的?
join on也是可以针对多个表来进行的~~select * from 表1 join 表2 on 条件1 join 表3 on 条件2

三张表 => 左表, 中表, 右表
先考虑左表和中表进行外连接. 得到一个"临时"表
再拿这个"临时"表和右表进行外连接
select * from 表1 [left/right] join 表2 on 条件1 [left/right] join 表3 on 条件2

自连接

~~ 奇淫巧技,特殊情况下的特殊操作,并非是一般用法,了解即可
自己和自己连接 => 自己和自己做笛卡尔积 => 这个操作本质上是把"行"转成"列"
~~ SQL中进行条件查询,都是指定某一列/多个列之间进行关系运算,
无法行和行之间关系运算,有的时候为了实现这种行之间的比较,就需要把行关系转成列关系
案例:显示所有“计算机原理”成绩比“Java”成绩高的成绩信息
“计算机原理” ,“Java” => course表里
成绩信息 => score表里
自连接需要指定表的别名

select 
	* 
from 
	score as s1, 
	score as s2 
where 
	s1.student_id = s2.student_id 
	and s1.course_id = 1 
	and s2.course_id = 3 
	and s1.score < s2.score;

SQL的逻辑表达能力是有限的.很多时候不是做不了,而是代价大.相比之下,使用Java这样的语言来描述复杂逻辑是更好的选择!!

子查询

两个字 ~~套娃 => 把多个查询语句合并成一个
~~子查询一旦嵌套的层次多了,对于代码的可读性是毁灭性的打击!!
子查询,在实际开发中使用的时候也要慎重!!!

单行子查询:返回一行记录的子查询
查询与“不想毕业” 同学的同班同学

-- 第一步
select 
	classes_id 
from 
	student 
where = '不想毕业';
-- 第二步
select 
	name 
from 
	student 
where class_id = 1;

-- 上面两步查询等效于下面的一步查询
select 
	name 
from 
	student 
where 
	classes_id = (select classes_id from student where name = '不想毕业');

多行子查询:返回多行记录的子查询
查询“语文”或“英文”课程的成绩信息

-- 第一步
select 
	id 
from 
	course 
where name = '语文' or name = '英文';
-- 第二步
select 
	* 
from 
	score 
where 
	course_id in (4, 6);
-- 上面两步查询等效于下面的一步查询
select 
	* 
from 
	score 
where 
	course_id in 
	(select id from course where name = '语文' or name = '英文');
合并查询

把两个查询语句的结果合并到一起
union关键字完成
~~ C 进阶里面,自定义类型详解.
struct => 结构体
union => 联合体 => 本质上就是让一个内存上的数据,可以有多种理解方式~好比一个人,有好多种身份是一样的
java里有没有union??为啥java就没有了呢??~~
~~ 时代变了!!!C 当年所面对的编程环境是比较的落后的~~ 计算机提供的硬件资源非常有限!!!内存只有几 kb,那就得把空间利用到极致~~ 后来计算机突飞猛进,此时,内存已经不值钱了 => union就没有用武之地了
小时候的游戏小霸王游戏机/红白机上的FC游戏魂斗罗,超级玛丽,一个游戏空间,大概64kb,大的是128kb.在64kb的空间里,有很多关卡,很多角色,很多npc,很多地图,很多道具,还有动画效果,音频效果,各种剧情…更可怕的是,还有3D游戏~~ => 对内存的空间利用达到了令人震惊的地步,那些年的开发FC游戏的程序猿,都是大神!!!
案例:查询id小于3,或者名字为“英文”的课程

select * from course where id < 3 or name = '英文';
-- 与下面的SQL语句等效
select * from course where id < 3 
union 
select * from course where name = '英文';

注:or只能针对一个表,而union可以把多个表的查询结果合(要求多个结果列得对应),适用范围更广一点,比or更强一些;
union会自动去重,union all 不会去重

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

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

相关文章

代码随想录 -- day45 -- 70. 爬楼梯 (进阶)、322. 零钱兑换 、279.完全平方数

70. 爬楼梯 &#xff08;进阶&#xff09; 这里要注意&#xff0c;这是一个排列组合的问题&#xff0c;所以要先遍历背包再遍历物品 dp[i]&#xff1a;爬到有i个台阶的楼顶&#xff0c;有dp[i]种方法 递推公式为&#xff1a;dp[i] dp[i - j] class Solution { public:int c…

基于51单片机万年历电压电流检测-proteus仿真-源程序

一、系统方案 本设计采用52单片机作为主控器&#xff0c;液晶1602显示&#xff0c;DS1302时钟检测&#xff0c;电流电压检测、按键设置报警&#xff0c;蜂鸣器报警。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 /lcd1602初始化设置*/ vo…

Java中什么是序列化,哪里有所应用

文章目录 一、简介1.1 本文介绍Java中的序列化技术1.2 阐述序列化的应用场景 二、Java序列化概述2.1 序列化定义2.2 序列化特征2.3 序列化机制 三、Java序列化使用3.1 实现Serializable接口3.2 transient关键字3.3 自定义序列化策略 四、Java序列化应用4.1 对象状态持久化4.2 网…

RCP系列-第一章 环境安装

RCP系列文章 第一章 Matlab安装 Matlab安装 RCP系列文章前言一、Matlab 获取二、安装1.解压2.打开解压后的文件夹中的【R2018b_win64】文件夹3.鼠标右击【setup】选择【以管理员身份运行】4.选择【使用文件安装密钥】&#xff0c;点击【下一步】5.选择【是】&#xff0c;点击【…

图像处理算法实战【1】超详细整理 | 新手入门实用指南 | 图像处理基础

1. 什么是图像 & 图像在计算机中如何存储&#xff1f;2. 图像可分为哪些类型&#xff1f; 2.1. 二值(黑白)图像2.2. 灰度图像2.3. RGB彩色图像2.4. RGBA图像 3. 什么是图像通道&#xff1f;4. 图像处理 4.1. 什么是图像处理&#xff1f;4.2. 图像处理流程4.3. 图像处理技术…

王道考研计算机网络

文章目录 计算机网络体系结构计算机网络概述计算机网络的性能指标 计算机网络体系结构与参考模型错题 物理层通信基础基础概念奈奎斯特定理和香农定理编码与调制电路交换、报文交换和分组交换数据报与虚电路 传输介质物理层设备错题 数据链路层数据链路层的功能组帧差错控制检错…

SpringSecurity一日干

前后端登录校验的逻辑 完整流程 本质就是过滤器链 1&#xff0c;提交用户名和密码 2&#xff0c;将提交的信息封装Authentication对象 3&#xff0c;传给下一个&#xff0c;调用2中的authenticate方法进行验证 4&#xff0c;3步骤也验证不了需要调用3的authenticate方法…

概念解析 | 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:CLIP和BLIP模型。 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍 🎯 [LB: 0.45836] ~ BLIP+CLIP | CLIP Interrogator | Kaggle 大纲: 背景介绍原理介绍和推导 CLIP模型BLIP模…

简易yum仓库搭建

目录 一、实验准备 二、获取yum仓库、安装httpd 三、客户机配置yum源 四、测试、验证 一、实验准备 准备两台主机&#xff1a; 192.168.115.148 &#xff1a;安装http 、作为yum仓库、挂载默认光盘 192.168.115.148 &#xff1a;作为客户机使用yum仓库、不挂载光盘 二、…

Dominosa/数邻(1) | C++ | 结构体和类

这里是目录 一、背景介绍二、题目描述三、Dominosa 的技巧&#xff1f;四、编程思路五、完整代码六、补充 一、背景介绍 你玩过骨牌吗&#xff1f;至少你一定听说过或者亲眼见过多米诺骨牌&#xff0c;而多米诺骨牌就发展自骨牌&#xff0c;这是一种古老的游戏&#xff0c;而我…

【Linux】VirtualBox安装Centos7

文章目录 下载并安装VirtualBox下载Centos镜像VirtualBox设置管理->全局设定&#xff1a;设定虚拟机默认安装路径工具->网络管理器&#xff1a;添加NetWork网络配置 VirtualBox安装CentOS7新建虚拟机&#xff0c;指定安装目录及名称&#xff0c;点击下一步指定虚拟机内存…

记录征战Mini开发板从无到有(二)

接上一篇&#xff0c;原理图设计完成后&#xff0c;就要画PCB图了。因为PCB直接影响板子的性能&#xff0c;所以决定花钱找一博科技的资深工程师来布板。布板效果非常好&#xff0c;细节处理得很到位&#xff0c;真的是专业的人干专业的事&#xff0c;话不多说&#xff0c;来欣…

无涯教程-JavaScript - OCT2BIN函数

描述 OCT2BIN函数将八进制数转换为二进制数。 语法 OCT2BIN (number, [places])争论 Argument描述Required/OptionalNumber 您要转换的八进制数。 数字不能超过10个字符。数字的最高有效位是符号位。其余的29位是幅度位。 负数使用二进制补码表示。 RequiredPlaces 要使用的…

python library reference

文章目录 1. 标准库2. Python标准库介绍3. 示例 1. 标准库 https://docs.python.org/zh-cn/3/library/ https://pypi.org/ https://pypi.org/search/ 2. Python标准库介绍 Python 语言参考手册 描述了 Python 语言的具体语法和语义&#xff0c;这份库参考则介绍了与 Pytho…

【多线程】线程安全 问题

线程安全 问题 一. 线程不安全的典型例子二. 线程安全的概念三. 线程不安全的原因1. 线程调度的抢占式执行2. 修改共享数据3. 原子性4. 内存可见性5. 指令重排序 一. 线程不安全的典型例子 class ThreadDemo {static class Counter {public int count 0;void increase() {cou…

openpnp - 二手西门子电动飞达的测试

文章目录 二手西门子电动飞达的初步测试概述飞达正常的判断标准先挑出一个手工控制好使的二手飞达用于测试.推料的手工检测扒皮的手工检测飞达测试的接线通讯的测试用串口助手测试通讯先看看是否发送给飞达的管脚是自己接的那个查看所有可以用到的上位机通讯命令M115 - 打印固件…

蓝桥杯官网练习题(颠倒的价牌)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小李的店里专卖其它店中下架的样品电视机&#xff0c;可称为&#xff1a;样品电视专卖店。 其标价都是 4 位数字&#xff08;即千元不等&#xff09;。 小李为了标…

BWMT的思考

从bw4开始&#xff0c;sap把建模的功能从系统的rsa1移除&#xff0c;改成BWMT的客户端。以前对java开发的eclipse不是很喜欢&#xff0c;总有点排斥。今天突然好像明白sap为啥要这样做&#xff1f; 1 最重要的是减少数据库的数据量和系统的负荷。把这种开发工作的程序和功能放在…

基于微信小程序美食菜品预订点餐预约系统uniapp+vue

点餐预约系统主要是为了提高用户的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对点餐预约系统的各个模块是通过许多今天的发达点餐预约系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则…

Games101作业5解读

文章目录 整体思路阅读Render 整体思路阅读 Scene scene(1280, 960);auto sph1 std::make_unique<Sphere>(Vector3f(-1, 0, -12), 2);sph1->materialType DIFFUSE_AND_GLOSSY;sph1->diffuseColor Vector3f(0.6, 0.7, 0.8);auto sph2 std::make_unique<Spher…