【MySQL】数据库约束与聚合查询和联合查询等进阶操作知识汇总

news2024/12/27 11:34:27

目录

    • 1.数据库约束:
      • 1.1 约束的类型:
      • 1.2 unique:
      • 1.3 primary key:
        • 1.3.1 分布式系统下,自增主键如何生成唯一id:
      • 1.4 foreign key:
        • 1.4.1 逻辑删除:
    • 2.表的设计/数据库的设计:
      • 2.1 数据库是如何设计的?
    • 3.进阶插入操作:
    • 4.进阶查询:
      • 4.1 聚合查询:
      • 4.2 group by 列名:
      • 4.3 联合查询/多表查询:
        • 4.3.1 内连接:
        • 4.3.2 外连接:
        • 4.3.3 自连接:
      • 4.4 子查询:
      • 4.5 合并查询:

1.数据库约束:

  1. 数据库约束是对数据库中的记录做出更详细的检查(检查数据是否合法,不能完全靠人工来检查)
  2. 和interface/abstract class的作用效果是类似的.

1.1 约束的类型:

(对于数据库中的记录做出更详细的检查)

类型说明
not null要求指定的列非空
unique表示值是唯一的, 触发查询
default本来默认值是null, default会修改默认值
primary key主键,针对每一条记录,作为身份标识
foreign key外键, 触发查询

和NULL比较:

= 或者 != 都不能和NULL比较

<=> 或者 is null 或者 is not null 可以和NULL比较

1.2 unique:

  1. unique的值唯一,每次插入/修改数据,都会针对当前的数据在表里进行查找,看这个值是否能查到!(如果查到了说明不唯一,就修改失败)在这里插入图片描述

  2. 当使用了unique之后,每次插入操作都会涉及到先查询再插入的操作.查询这里就涉及到遍历,遍历的效率比较低,因此就用到了索引!

  3. 使用unique约束,数据库就会自动的给对应的列创建索引.

1.3 primary key:

  1. 就类似与身份证,作为一个人的身份标识一样.

  2. 主键是一个身份标识,既要保证唯一性又不能为空;因此primary key相当于是unique + not null;

  3. 一个表里,主键只能有一个, unique则是可以有多个的.

  4. 使用主键需要给这个列设置一个唯一的值,如果这个分配值的工作人工来完成的话就很麻烦(需要人工来保证使用的身份标识没有重复), 因此MySQL中就引入了一个机制自增主键(通过自增这样的方法来给主键设置值).

  5. 使用自增主键primary key auto_increment的时候,就不需要手动来设置值了,只需要把这一列设置为null即可.

  6. 虽然自增主键是自动分配的,但是也能手动设置.在这里插入图片描述

  7. 自增主键可以理解成是数据库里记录了当前最大的id是多少,每次都是从最大值之后再进行增加的.

1.3.1 分布式系统下,自增主键如何生成唯一id:

  1. 如果数据库服务器就一个,那自增主键就可以保证主键的唯一性,但是如果数据时分布式部署的(数据太大了,一台机器存放不下,使用多台机器存储).这个时候就要分库分表.但是这些数据逻辑上还是同一张表只不过是存储在不同的机器上,此时原有的自增主键就失效了(MySQL的自增主键只能保证单机上不会重复,不能保证分布式部署不重复).

  2. 分布式系统下生成唯一ID的算法: 生成公式 = (时间戳 + 机房编号 / 主机的编号 + 随机因子) => 计算 哈希值;

  3. 随机因子:随机数,理论上保证不了俩次生成的随机数是不同的,但是工程上实验上随机因子冲突的概率是非常小的因此就忽略不计了.

1.4 foreign key:

  1. 作用是把俩张表关联起来.

  2. 例如:现有学生表和班级表.学生表里的每个记录中都包含了班级编号,这个班级编号要在班级表中存在!

  3. 举个例子,有一天一个人加我好友,说是和我一个专业的3班的同学,我一听就不对劲.俺们专业没有3班呐. 这就叫外键约束.

  4. 班级表就对学生表产生了约束.班级表(约束别人的表)称为是父表;学生表(收到约束的表)称为是子表;在这里插入图片描述

  5. 在外键的约束下插入数据会触发查询.往学生表中插入数据就会自动的在班级表中查询,看这个classId是否存在, 如果存在则插入成功,否则插入失败.

  6. 这里也有要求,子表中引用父表的这一列,务必是primary key 或者 unique . 这里指的是父表.

  7. 在外键中,父表对于子表产生了约束.子表也是会对父表有约束的.如果在子表存在的情况下,直接删除父表就会出现问题. 父表删除记录也要看当前这个记录是否被子表引用,如果被引用的就不能删除,不被引用的才能删除/修改.

1.4.1 逻辑删除:

  1. 父表->商品表(goodsId,name,price…); 子表->订单表(orderld,time,goodsld…);如果某个商品下架了,就需要把goodsId给删了,但是子表中引用了父表的goodsId所以删不掉,此时就涉及到了逻辑删除.将商品表的数据标记成无效,这里说的逻辑删除就是对这个标记位进行修改.
  2. 但是这样的话,就会导致硬盘空间被持续占用,岂不是很浪费空间嘛??其实硬盘空间很大的,而且很便宜.


2.表的设计/数据库的设计:

2.1 数据库是如何设计的?

  1. 这个问题从这个几个方面回答: 数据库中有几个表?/每个表都是干啥的?/每个表里都有哪些列?/这些列又是干啥的?
  2. 数据库设计主要思路: a)根据需求找到实体 —> b)再梳理清楚实体之间的关系(一对一/一对多/多对多关系)
  3. 找实体的过程说的就是需求中的关键性的名词, 一般来说每个实体都会安排一个表.
  4. **一对一关系:**一个人只有一个身份证号,一个身份证也只对应一个人.
  5. **一对多关系:**一个班级可以包含多个学生,一个学生只属于一个班级.
  6. **多对多关系:**一个学生可以选择多门课程,一门课程也可以拥有多个学生.多对多的表结构通常需要使用一个"关联表"把俩个实体的表给联系起来.
  7. 除此之外的关系就是没关系.


3.进阶插入操作:

insert into 表名1 select 列名 from 表名2:

  1. 可以把查询的结果插入到另一个表中, insert into student2 select * from student1;把student1里查询出来的结果插入到student2中.
  2. 这里的插入不一定是把student1里的数据全都插入过去,也可以只插入一部分(通过条件来筛选)
  3. insert into student2 select * from student1; 这里查询的结果的列要和插入的表的列要匹配(列的个数和类型是要匹配)在这里插入图片描述


4.进阶查询:

4.1 聚合查询:

  1. 查询的时候带表达式是把列和列放到一起进行计算.
  2. 聚合查询是行和行放到一起进行计算
  3. SQL里面提供了一些函数, 通过这些函数就可以进行行和行的运算.
函数说明
count( )计算行数
sum( )针对这一列的若干行之间进行加和,只能针对数值类型
avg( )求这一列的若干行的平均值,只能针对数值类型
max( )求这一列的若干行的最大值,只能针对数值类型
min( )求这一列的若干行的最小值,只能针对数值类型

函数: count( ) / sum( ) :

  1. count(*)是查询结果中有多少行,即使有一行是空值也会记录到行数里.
  2. count(列名)如果遇到有一行是空值,则不会记录.
  3. sum(列名),如果这一列中有null,那么null不参与运算,直接跳过.
  4. sum(列名)这样的运算只能针对数字来进行,不能针对字符串.

4.2 group by 列名:

  1. 可以使用, group by 列名;来根据查询的结果进行分组操作,把值相同的记录分成一组,然后就可以针对每一组分别进行聚合了.

  2. group by 的效果:在这里插入图片描述

  3. 如果直接写成select * from emp group by role;展示出的就是每一组的第一条数据.在这里插入图片描述

  4. 在进行分组查询的时候,只有用来分组的这一列,可以进行查询,其他的列则必须要搭配聚合函数来查询.在这里插入图片描述

  5. 分组查询的时候还可以指定条件,在分组之前使用条件筛选需要用到where ; 在分组之后使用条件查询需要用到having .(where和having可以同时使用!)

(一) 查询每个岗位的平均薪资(除掉张三的这条记录).先把张三这条记录删掉,再分组.where要写到group by的前面.

在这里插入图片描述

(二) 查询平均薪资 > 12000的岗位.先分组算好平均薪资之后再找到大于12000的岗位.having要写到group by后面.

在这里插入图片描述

(三) 求除了张三之外.每个岗位的平均薪资并且保留出平均薪资 >= 12000的岗位.

在这里插入图片描述

4.3 联合查询/多表查询:

  1. 要想了解多表查询先了解"笛卡尔积".

  2. 笛卡尔积就是简单粗暴的排列组合把所有可能的情况都列出来,把俩张表的记录放在一起进行排列组合出所有可能的情况.

  3. 笛卡尔积的列数是俩个表的列数之和; 笛卡尔积的行数是俩个表的行数之积.笛卡尔积可以指定列(表达式/别名/去重).在这里插入图片描述

  4. 在进行联合查询的过程就是在计算笛卡尔积的过程,当表比较大的时候,如果进行多表查询就会非常的低效,甚至称为"危险操作".

  5. 笛卡尔积的有些数据是有意义的,有一些是无意义的, 用来筛选笛卡尔积有效数据的条件称为"连接条件".

  6. 联合查询/多表查询 = 笛卡尔积 + 连接条件 + 其他条件(根据其他的需求)

  7. SQL中的使用来获取到笛卡尔积.(使用 , 或者 使用 join on),有些特定的场景务必需要使用 join on.在这里插入图片描述

4.3.1 内连接:

案例 :
在这里插入图片描述

(一) 查询"许仙"同学的成绩;

1.计算student和score的笛卡尔积

select * from student,score;

2.给笛卡尔积加上连接条件

select * from student,score where student.id = score.student_id;

3.根据许仙这个名字,再进行筛选

select * from student,score where student.id = score.student_id and student.name = “许仙”;

4.精简查询的结果,保留关注的,去掉不关注的信息

select name,score from student,score where student.id = score.student_id and student.name = “许仙”;

使用 join on 来完成

select name,score from student join score on student.id = score.student_id and student.name = “许仙”;

(二) 查询所有同学的总成绩(各科之和)

1.计算student和score的笛卡尔积

select * from student,score;

2.加上连接条件

select * from student,score where student.id = score.student_id;

3.分组

select * from student,score where student.id = score.student_id group by name;

4.精简查询的结果

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

(三) 查询出所有同学的成绩,带课程名的那种

同学名字在学生表里/课程名字在课程表里/分数在分数表里

1.计算三张表的笛卡尔积

select * from student,score,course;

2.给笛卡尔积加上连接条件

select * from student,score,course

where student.id = score.student_id and classes.id = score.course_id;

3.不必加其他的条件了,直接精简即可

select student.name,course.name,score from student,course,score

where student.id = score.student_id and course.id = score.course_id;

使用 join on 来做,更能体现出"俩俩结合"的感觉

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

4.3.2 外连接:

from 表1,表2 where …; 这就是内连接

from 表1 join 表2 on …; 使用join/inner join可以作为内连接也可以作为外连接

  1. 写成 left join 左外连接 / right join 右外连接.

  2. 如果三个表外连接, 则是A和B先外连接得到一个临时表, 把临时表和C建立连接即可.

  3. 如果俩张表的数据都是一一对应的时候,其实内连接和外连接看不出来区别在这里插入图片描述

  4. 如果表上的数据不在一一对应,内连接和外连接区别就非常明显了.下面的数据中,左侧表的王五同学在右侧表里没有成绩,右侧表中的4号同学在左侧表里没有同学信息.在这里插入图片描述

  5. 在这里插入图片描述

  6. 在这里插入图片描述

  7. 左外还是右外,主要还是看表的先后顺序, 是在join的左侧还是右侧.在这里插入图片描述

4.3.3 自连接:

  1. 自己和自己做笛卡尔积

  2. 条件查询中核心就是列和列之间的比较,而从来没有行和行之间的比较.此处的自连接就是把行转成列.

  3. 如果这个表很大,那么运行的开销就会很大,可读性也不高.

(一) 显示计算机原理比java成绩高的同学

1.需要的数据都在分数表里,

select * from score as s1,score as s2;

2.加上连接条件

select * from score as s1,score as s2 where s1.student_id = s2.student_id;

3.加上筛选条件

select * from score as s1,score as s2

where s1.student_id = s2.student_id and and s1.course_id = 3 and s2.course_id = 1

and s1.course_id > s2.course_id;

4.4 子查询:

  1. 本质上就是把多个查询语句组合成一个查询语句, 套娃!
  2. 用一个查询的结果的临时表,基于这个临时表再发起另外一组查询
  3. 如果子查询返回的结果是多条记录,就可以使用 in 来进行子查询.

(一) 查询出与不行毕业同学的同班同学

select name from student where name != “不想毕业” and

classes_id = (select classes_id from student where name = “不想毕业”);

(二) 查询语文或英文课程的成绩信息

select * from score where course_id in (select id from course where name = “语文” or name = “英文”);

4.5 合并查询:

  1. 使用 union 或者union all 来完成俩个查询的结果合并到一起.如果是一张表那么union的作用和 or 类似,使用or也能完成.如果是俩张表就不能使用or了,使用俩张表合并的话列需要列是匹配的.
  2. union 是把多个查询的结果集合并成一个,如果有重复的数据,就会去重.
  3. union all 合并的时候如果有重复的数据就不会去重.

(一) 查询课程 id<3 或者名字为英文的课程

select * from course where id < 3 union select * from course where name = “英文”;

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

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

相关文章

2508. 添加边使所有节点度数都为偶数 c++

给你一个有 n 个节点的 无向 图&#xff0c;节点编号为 1 到 n 。再给你整数 n 和一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间有一条边。图不一定连通。 你可以给图中添加 至多 两条额外的边&#xff08;也可以一条边都不添加&#x…

C51——定时器控制寄存器

定时器的本质原理&#xff1a; 每经过一个一起周期&#xff0c;就加1 在寄存器里加 当我们想要操作寄存器的时候 就要找到TCON 当它开始数数的时候&#xff0c;会有天花板&#xff0c;会有溢出。 那我们怎么知道他溢出了&#xff1f;有TF0&#xff0c;当TF0 出现变化的时…

【剧前爆米花--爪哇岛寻宝】

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于接口的文章&#xff0c;在本篇文章中我会将接口常用的一些实例进行讲解&#xff0c;以及部分方法在重写中的思想。 目录 Comparable和Comparator接口使用 Object类 t…

JDBC的简单使用与封装

目录 1、JDBC 2、JDBC的常用接口 1.Driver接口 2.Connection接口 3.Statement接口 4.ResultSet接口 3、JDBC的基本使用 1&#xff09;、简单的增删查改 Ⅰ、查 Ⅱ、增 Ⅲ、改 Ⅳ、删 2&#xff09;简单封装 1、JDBC 我们先了解JDBC是什么&#xff0c;JDBC的全称是Java数…

2018年全国职业技能大赛中职组“网络安全”赛项—基础题(解析)

2018年全国职业技能大赛中职组“网络安全”赛项—基础题&#xff08;解析&#xff09; 任务一、nmap 1、nmap sP -n 192.168.100.133 //进行ping扫描 1.1、nmap -Pn -n 192.168.100.133 //目标禁用 绕过ping 扫描 2、nmap -A -n ip // 对ip进行综合性扫描 3、nmap -O -n…

TiDB-学习笔记

编写这个笔记&#xff0c;希望能记录下学习TiDB时候的知识点。 目录 第一章 1.事务 1.1 SQL-92标准&#xff1a; 1.2 事务的隔离级别 2.在TiDB学习 SQL 语句 第二章 第三章 第一章 1.事务 事务的特性&#xff08;ACID&#xff09; atomicity原子性、consistency一致性、i…

网上花店网页代码 html静态花店网页设计制作 dw静态鲜花网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

全志V853 在 NPU 转换 YOLO V3 模型

NPU 转换 YOLO V3 模型 YOLO 全称是 You Only Look Once&#xff08;你只需看一次&#xff09;&#xff0c;从名称上也能看出这种算法速度快的优势&#xff0c;因此在许多边缘设备上&#xff0c;YOLO 算法的使用十分广泛。YOLOV3 是华盛顿大学研究生 Joseph Redmon 所开发&…

matlab学习笔记(九)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 matlab学习笔记&#xff08;九&#xff09;一、信号采样二、信号重建一、信号采样 信号的采样原理图如下图所示&#xff1a; 其数学模型表示为&#xff1a; 其中的f(t)为原…

11、Mysql高级之SQL优化

11、Mysql高级之SQL优化 文章目录11、Mysql高级之SQL优化0 SQL优化1 大批量插入数据2 优化insert语句3 优化order by语句3.1 环境准备3.2 两种排序方式3.3 Filesort 的优化4 优化group by 语句5 优化嵌套查询6 优化OR条件7 优化分页查询7.1 优化思路一7.2 优化思路二8 使用SQL提…

【Budibase】搭建低代码开发平台

Budibase介绍 Budibase 是一套开源的低代码开发平台&#xff0c;支持一键数据库及API 接入&#xff0c;支持简单的 JS 关联前后端数据&#xff0c;有细致的权限访问管理&#xff0c;对移动端有良好的支持。它主打企业流程自动化&#xff0c;有完善的自动化流程设计&#xff0c…

NETDMIS5.0界面介绍

1.启动界面介绍 双击桌面快捷方式&#xff0c;打开NET.DMISS启动界面如下图&#xff0c;包含三个菜单是文件、设置语言、帮助。 2.工作界面介绍 默认测量界面包括主菜单&#xff0c;工具条&#xff0c;节点程序界面&#xff08;显示测量过程&#xff09;&#xff0c;CAD视窗…

(免费分享)基于ssm简易网盘系统

开发工具&#xff1a;IDEA&#xff0c;mysql5.7 Tomcat8.0&#xff0c;jdk1.8 package cn.tangtj.clouddisk.web;import cn.tangtj.clouddisk.entity.User; import cn.tangtj.clouddisk.utils.UserUtil; import org.apache.logging.log4j.LogManager; import org.apache.loggi…

嵌入式应用开发|Linux文件I/O常用的四种访问方式

在Linux系统中&#xff0c;一切都可以看成"文件"<通常包含&#xff1a;普通文件、驱动文件、网络通信文件等等>&#xff0c;系统中所有的操作都可以通过文件I/O实现&#xff0c;因此&#xff0c;掌握文件常用接口很有必要。 0.前言 屏幕前的你如果懂得main函数…

SAP S4 如何快速配置一家公司

之前配置公司采用的方法是copy的方式来配置&#xff0c;后来在做其他配置的时候发现&#xff0c;copy的方法会把很多不需要的配置也copy进来了。所就我从新定义了一个公司来进行学习研究。配置一定空的公司很简单&#xff0c;只需要三步&#xff1a; 1 定义和分配公司 • 公司…

Java中的异常、IO与NIO面试题

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java面试题…

萤石网络通过注册:9个月净利2亿同比降28% 海康威视为大股东

雷递网 雷建平 12月19日杭州萤石网络股份有限公司&#xff08;简称&#xff1a;“萤石网络”&#xff09;日前通过注册&#xff0c;准备在科创板上市。萤石网络计划募资37.39亿元&#xff0c;其中&#xff0c;22亿元用于萤石智能制造重庆基地项目&#xff0c;8亿元用于新一代物…

论文投稿指南——中文核心期刊推荐(航空、航天)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

做Python网络爬虫需要掌握哪些核心技术?

在当下这个社会&#xff0c;如何有效地提取并利用信息成为一个巨大的挑战。基于这种巨大的市场需求&#xff0c;爬虫技术应运而生&#xff0c;这也是为什么现在爬虫工程师的岗位需求量日益剧增的原因。那么做Python网络爬虫需要掌握哪些核心技术呢&#xff1f;下面我们来一起看…

机器学习 特征工程及模型聚合

目录 一&#xff1a;什么是特征工程 二&#xff1a;特征工程方法 三&#xff1a;独热编码 四&#xff1a;归一化处理 五&#xff1a;特征工程方法 六&#xff1a;特征工程处理过程 七&#xff1a;Kaggle房价预测实际案例 一&#xff1a;什么是特征工程 1 是最大限度地从…