MySQL 表的增删改查

一、什么是CRUD?

大家肯定跟我一样,看到CRUD这四个字母一头雾水,什么是CRUD呀?
这里我就为大家一一讲解:

CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写

是数据库操作最基本的操作
也是未来我们进入公司实习,最开始的最日常的工作
由此可见,对我们未来涞水非常的重要


所以,接下来就让我们来看看具体什么是CRUD吧

二、新增(Create)

在MySQL中 使用 insert 来往表里插入数据

但是大前提是,选中数据库,并且创建好对应的表

inse into 表名 values  (列,列......)

括号里面的给出的数目和类型,都是要和表结构匹配的
在这里插入图片描述


那么这里就有人要问了,能不能插入字符串呢?
sql中,字符串是可以使用的
很多编程语言都没有“字符”类型,这种情况一般 ’ 和 " 都能表示字符串

但是MySQL 5,默认字符集是拉丁文,无法直接插入中文的,都需要在创建数据库的时候显示设定好的字符集
在这里插入图片描述
在这里插入图片描述

1、单行数据 + 全列插入

插入两条记录,value_list 数量必须和定义表的列的数量及顺序一致

如果列的类型不匹配MySQL会尝试自动把字符串转成整数,就会报错
在这里插入图片描述

这个时候,可以通过特殊的写好,让这种操作可以成功,比如指定列进行插入

2、多行数据 + 指定列插入

在这里插入图片描述
这个时候,在name 列是没有数据的
在这里插入图片描述


当然也可以一行插入多组数据
在这里插入图片描述

这个时候有的人就会想:一次插入十个数据 和 十次分别插入一个,哪个执行效率会比较高呢?
显然是一次插入十个数据
因为MySQL是通过客户端去找服务器,服务器接收到sql之后再进行处理的
因此,每个sql都涉及上述这样的交互过程
所以显然第一种情况会更好

3、插入特殊类型

上述我么都是进行了插入数字、字符串,相对于来说就比较简单

接下来我们进行插入datetime 类型

比较简单的写法,直接使用特定的格式化字符串,表示时间日期

在这里插入图片描述

在这里插入图片描述
这属于MySQL支持的一种标准化格式
这是一个“标准化时间字符串”,MySQL会自动解析这个字符串,转换成8个字节的时间戳

当然也可使用 now() 这样的函数,直接获取当前的时间日期
在这里插入图片描述
在这里插入图片描述

三、查询(Retrieve)

查询是数据库操作中最常见的用法
学好查询非常重要
接下来就让我们一起进入查询的学习

1、全列查询

select * from 表名;

这里 * 被称为通配符


注意:
select * from 表名; 这个操作非常危险
一旦表中数据量过大,就会导致整个数据库崩盘
并且可能会影响到索引的使用

在这里插入图片描述

2、指定列查询

select 列名, 列名...... from 表名;

在这里插入图片描述
在查询的时候 要确保列的名字 和 表的列的名字是一致的(顺序是随意的)

3、表达式查询

可以在查询的过程中,指定表达式(把查询出来的每一行,都带入表达式进行运算)
在这里插入图片描述
有的人在看到新查的表会有疑惑,这是个新的表吗?会在数据库中改变表吗?

在当前的表达式查询中,并没有修改服务器上硬盘存储的数据本题,只是在查询结果的基础上进行运算的,得到的是一个**“临时表”**

此处查询出来的临时表,每个列的类型不在受限于原始表

这个临时表在查询炒作结束的时候,数据就消失了,数据的本题内容不会发生任何改变

select 进行的任意操作,都不会修改数据本体!!!

4、指定别名

 select 表达式 as 别名 from 表名:

在这里插入图片描述

5、去重

查询的视乎,进行去重
查询结果中如果存在重复的元素,就只保留一个

select distinct 列名 from 表名;

在这里插入图片描述

6、排序

查询的同时,进行排序

select 列名 from 表名 order by 列名;

最后面那个列名,就是排序的一句(列名不一定出现在 select 的列名中)
在这里插入图片描述这样就构成了升序排序
在这里插入图片描述
这样就是降序排序 就是在后面加了dese


字符串虽然也可以排序,但是这个时候排序大部分情况 不符合需求
“字典序”中文字典序是没有意义的
在这里插入图片描述


order by 可以指定多个列来进行排序
指定多个列的时候,就也是带有“优先级”的
前面的列,优先级高,后面的优先级低
优先级高的列值相同,才会比较优先级低的列
在这里插入图片描述
先按照数学成绩排序,如果数学成绩相同,在按照语文成绩排序
在这里插入图片描述
先按照数学成绩升序排,如果数学相同,再按照语文成绩降序排
在这里插入图片描述
先按照数学成绩降序排,数学相同,再按照语文成绩降序排

7、条件查询

查询的时候,指定筛选条件
条件满足,这个数据就被保留(最为结果集,最终的结果集,就是所有满足条件)
不满足,这个数据直接跳过

执行条件查询的时候,就会遍历整个表,把每个记录都带入到条件中,看条件是否满足

在这里插入图片描述

基本查询:

  1. 查询英语成绩不及格的同学即英语成绩(< 60)
    在这里插入图片描述
  2. 查询语文成绩好于英语成绩的同学
    在这里插入图片描述
  3. 查询总分在200 分以下的同学
    在这里插入图片描述
    在这里不可以取别名来进行查询

AND与OR:

  1. 查询语文成绩大于80分,且英语成绩大于80分的同学
    在这里插入图片描述
  2. 查询语文成绩大于80分,或英语成绩大于80分的同学
    在这里插入图片描述
  3. 观察AND 和 OR 的优先级
    AND 的 优先级高于 OR

一个where 中,有and 也有 or,此时会先执行 and,后执行 or
在这里插入图片描述

范围查询:

  1. BETWEEN … AND…

查询语文成绩在 [80, 90] 分的同学及语文成绩
在这里插入图片描述
使用 AND 也可以实现
在这里插入图片描述
2. IN

查询数学成绩是 78 或者 59 或者 98 或者 99 分的同学及数学成绩
在这里插入图片描述
使用 OR 也可以实现
在这里插入图片描述

模糊查询:LIKE

在这里用到了通配符
%:匹配任意个任意字符
_:匹配一个字符


匹配名字中以孙 开头的同学
在这里插入图片描述
‘孙%’ 以孙开头
‘%孙’ 以孙结尾
‘%孙%’ 包含孙的


_ 只能匹配到一个任意字符
在这里插入图片描述
在这里插入图片描述

NULL 的查询:IS [NOT] NULL

MySQL支持的模糊查询,规则是比较简单的
除了各种编程语言,还有一种模糊匹配的方式,“正则表达式”
在这里插入图片描述

8、分页查询:LIMIT

select * 比较危险,一次查出来的内容太多了

分页查询则是最适合的能解决上述问题的方案
可以限制这一次查询,最多可以查多少记录
在这里插入图片描述
在这里插入图片描述
在操作生产环境数据库的时候
最好在查询的时候都加上limit

四、修改(Update)

update 表名 set 列名 = 值 where 条件;

在这里插入图片描述
update 的操作是修改硬盘数据


将孙悟空同学的数学成绩变更为 80 分
在这里插入图片描述


将总成绩倒数前三的 3 位同学的数学成绩加上 1 分

这个时候我们先查看一下总成绩倒数三名
在这里插入图片描述
由于空值在排序的时候,会被当做最小
所以先删了
再次查询
在这里插入图片描述
接下来就要将这三个人的数学成绩加1
在这里插入图片描述
在这里插入图片描述


修改语文成绩,改成0
在这里插入图片描述

五、删除(Delete)

delete from 表名 where 条件 / order by / limit;

把条件匹配出来的符合要求的记录,给删除掉


删除行者孙的成绩
在这里插入图片描述


如果删除语句没有指定任何条件,就会删除表里的所有数据
删除所有记录 和 删表 还是有一些差别的

drop table 是把表本身 和 表里的数据都删掉了
delete 则只是删除了表里面的数据

六、数据库约束

1、约束类型

在这里插入图片描述

2、NULL约束

创建表时,可以指定某列不为空
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、UNIQUE:唯一约束

加上 unique 约束之后,后续进行插入/修改的时候,都会先进行查询,看看当前这个值是否已经存在

约束,能够引入更多的检查操作,也会增加系统的开销
在这里插入图片描述

4、DEFAULT:默认值约束

默认情况下 默认值就是 NULL
进行指定列插入,其他未被指定的列就会被设为默认值
在这里插入图片描述

在这里插入图片描述


接下来让我们加上约束条件
在这里插入图片描述
这个时候默认值就会改变
在这里插入图片描述
这样操作是因为,很多时候,如果返回一个null,是一个不好的体验
尤其不应该把null 这样的字眼,呈现到普通用户眼前

5、PRIMARY KEY:主键约束

主键,用来作为一个记录的身份标识

在这里插入图片描述
一个表里只有一个主键
通常会使用像图上 xxx id这样的列作为主键

但是还有一种情况,叫做联合主键,只有一个主键是由多个列联合构成的


主键是非空并且是唯一
一旦插入错误就会插入失败
在这里插入图片描述
主键是不允许重复的,但是怎么确保它不重复呢?
MySQL自身给我们提供了一种机制,“自增主键”
在这里插入图片描述
红色圈起来的地方,只是当前这个id,不需要用户自己指定了,可以交给数据库,让数据库自行进行分配
如下图所示:
在这里插入图片描述
在这里插入图片描述


注意:
每次使用null 的方式插入自增主键的时候
都是数据库会根据当前这一列的最大值,在这个基础上,继续进行递增

在这里插入图片描述
这里的递增不会重复使用之前的值的
在这里插入图片描述


上述自增主键,只能在单个数据库下生效
如果数据库是由多个MySQL服务器构成的“集群”,此时,自增主键就无法生效了

当表里面的数据挺特别多,一台机器存不下,就需要使用多个机器,把表里面的数据一分为二,每台机器存一半

此时,这两个机器的主键,就是各自自增各自的了
这就可能导致,第一个机器中的数据的id 和 第二个机器的数据 id 重复了

实际上在业务中引入“主键”是希望不会重复的

确保一个分布式系统中,能够存在唯一的 id,业界也有一些分布式系统生成唯一的 id 算法。如下:
把这个主键,设置成字符串类型(里面包括一个时间戳,主机的编号,随机因子)
按照这个思路,生成的主键字符串,就可以确保分布式系统下,也是唯一的

6、FOREIGN KEY:外键约束

外键约束是存在于两个表之间的,因此我们目前需要两个表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个时候王五同学不在班级表中存在,因此这是一个不太科学的非法数据
引入外键约束,就是为了解决这样的问题

希望学生表中的classId 都要在班级表中存在,就可以使用外键约束来进行校验


语法:

   foreign key (字段名) references 主表(列)

在这里插入图片描述
在这里插入图片描述
前面的约束,都是在定义表的时候,哪一列需要学术,就创建到哪一列的后面
外键约束,则是写到最后,把所有前面的列都定义好了之后,在最后面通过 foreign key 创建外键约束

这种情况下,也可以认为,班级表,约束了学生表
把班级表这种约束别人的表,称为“父表”
把学生表这种被别人约束的表,称为“子表”
在这里插入图片描述
引入外键约束之后,新增一个记录,就会先在对应的父表中查询,看看是否存在,如果不存在,就会报错

在这里插入图片描述
修改也是不可以的


注意:
外键约束,是双向的
在这里插入图片描述
这个时候如果想删除父表的数据,就可能有问题
在这里插入图片描述
先要删除父表的这个数据,就必须先删除子表中的对应的数据,确保子表中没有数据
这样引用父表的记录,再能真正删除
在这里插入图片描述
尝试删除/修改父表中的记录,也会先查询子表,看看当前这个结果是否在子表中被引用,如果被引用,就会删除失败

使用外键约束的时候,操作子表,要查询父表;操作父表,也要查询子表
如果表数据很多,查询操作就会非常低效
为了让上述查询更加高效一些,往往就需要要求 子表中的列和父表中被引用的列,都要带有“索引”
在这里插入图片描述

7、逻辑删除

在实际的数据库应用中,我们经常会遇到一些问题:
比如:在淘宝买东西时之后,商品会有订单表,但是如果商品下架了,订单表还在,但是商品表就消失了
此处是可以用外键约束的,但是引入外键约束后,后续这个商品如何下架呢?
其最终的问题是,如何在使用外键约束的前提下,删除商品表中的数据,但是不影响订单表

这个时候,就需要进行逻辑删除
在这里插入图片描述

这个时候,用户想要查询商品列表,就可以通过where isOnlin = 1 就可以确保不会把下线的商品查询出去
如果需要下线,就直接把 isOnline 改成 0

上述做法,书没有真正删除(硬盘空间依然被占用),只是“逻辑上”标记无效了

不仅仅在数据库,其实很多场景也会用到逻辑删除的思路
电脑上的文件,进行删除也是逻辑删除,不是正在的删了
你把文件删掉,其实就是在系统中,把硬盘对应的盘块数据标记无效了,理论上都是可以恢复数据的

七、表的设计

对于“数据库设计”就是根据需求,把你需要的表创建出来
对此有两点要求:

  1. 先根据需求,找到实体
    对于一些关键性质的对象,要梳理清楚需求,提取出关键的名字
    一般来说,每个实体,都需要安排一个表

  2. 梳理清楚实体之间的关系
    多个实体之间,需要理清楚关系,不同的关系下,有不同的设计表的方式

1、一对一

一个学生只有一个学号,一个学号也只对应一个学生,这就是一对一的关系
在这里插入图片描述

在一对一的关系下,表结构就有以下几种设计方案:

方案一:创建一个大表,把需要的所有信息都放在一起
但是,如果这两个表都很简单(列很少)可以烤炉合并,如果这两个表都很复杂(列很多)不建议合并

方案二:分两个表,使用 id 来引用过来,建立联系
在这里插入图片描述
在这里插入图片描述

2、一对多

在学校教务系统,有一个实体,学生,还有一个实体,班级
一个班级可以包含多个学生,一个学生只能属于一个班级
在这里插入图片描述
针对一对多,设计表结构,也存在两种方案:

方案一:
在这里插入图片描述
方案二:
在这里插入图片描述
由于MySQL 的类型中,不支持“数组”这样的类型,方案一是行不通的,只能使用方案二

3、多对多

在教务系统中,学生是一个实体,课程是一个实体
一个学生可以选择多种课程,一个课程也可以被多个学生选择
在这里插入图片描述
设计数据库也有定式
在这里插入图片描述

4、两个实体毫不相关

八、查询(进阶)

1、 查询搭配插入

查询可以搭配插入使用

把查询语句的查询结果,作为插入的数值

此处要求 查询出来的结果集合,列数/类型 要和插入的这个表匹配

在这里插入图片描述

2、 聚合查询

表达式查询,是针对 列和列 之间进行运算的
聚合查询,相当于是在 行 和 行 之间进行运算的

sql 中提供了一些“聚合函数”来完成上述行之间的运算

在这里插入图片描述


先执行 select * ,再针对结果集合进行统计(看看具体有几行)
在这里插入图片描述
在页面中我们是可以看到行数的为什么还要使用 count 呢?
因为这是 mysql 客户端内置的功能,如果通过代码来操作 mysql 服务器,就没有这个功能了

另外,count(*) 得到的结构还可以参与各种算数运算,还可以搭配其他 sql 使用

在这里插入图片描述

指定列进行去重

在这里插入图片描述


SUM([DISTINCT] expr)
把这一列的若干行,给进行求和(算数运算)
只能针对数字类型使用

在这里插入图片描述
在这里 null 不会进行相加

在这里插入图片描述
字符串不能相加,会有警告
在这里插入图片描述
在这里插入图片描述
这里就是把 007 当做数字,转换成了 double 类型

sum(表达式):
在这里插入图片描述

  1. select chinese + math +english
    把对应的列相加,得到一个临时表
  2. 在把这个临时表的结果进行行和行相加

AVG([DISTINCT] expr)
返回查询到的数据的 平均值,不是数字没有意义

在这里插入图片描述


MAX([DISTINCT] expr)
返回查询到的数据的 最大值,不是数字没有意义

在这里插入图片描述


MIN([DISTINCT] expr)
返回查询到的数据的 最小值,不是数字没有意义

在这里插入图片描述

3、GROUP BY子句

使用 group by 进行分组,针对每个分组,再进行聚合查询

针对指定的列进行分组,把这一列中,值相同的行,分到一组中
这样就会得到若干个组,针对这些组,分别使用聚合函数


如果直接查询,就会出现线吗这种情况
在这里插入图片描述
导致信息不准确

这里我们就需要把每种岗位进行分组
在这里插入图片描述


使用 group by 的时候,还可以搭配条件
需要区分清楚,该条件是分组之前的条件,还是分组之后的条件

  1. 查询每个岗位的平均工资,但是排除张三
    直接使用 where 即可,where 子句 一般写在 group by 的前面
    在这里插入图片描述
  2. 查询每个岗位的平均薪资,但是排除平均薪资超过 2w 的结果
    使用 having 描述条件,having 子句一般写在 group by 的后面
    在这里插入图片描述
  3. 在 group by 中,可以一个 sql 同时完成这两类条件的筛选
    查询每个岗位的平均薪资,不算张三,并且保留平均薪资超过 2w 的结果
    在这里插入图片描述

4、联合查询/多表查询

前面的查询,都是针对一个表
相比之下,则是一次性需要从过个表中进行查询

联合查询,关键思路,在于理解“笛卡尔积”工作过程


准备表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


查询“许仙”同学的成绩

通过 student 和 score 表进行联合查询

  1. 先把这两个表,进行笛卡尔积

在这里插入图片描述

  1. 加上连接条件,筛选出有效数据
    学生表的 id = 分数表的 student_id

在这里插入图片描述

  1. 结合需求,进一步添加条件,针对结构进行筛选
    此处是 查询 许仙的成绩
    就可以加上一个 student.name = ‘许仙’

在这里插入图片描述

  1. 针对查询到的列进行精简,只保留需求中关心的列

在这里插入图片描述


查询所有同学的总成绩,及同学的个人信息
此时同学成绩是按照 行 来组织的
此处就是多行数据进行嘉禾,使用聚合函数 sum
还需要按照同学进行分组

基于多表查询和聚合查询综合运用

  1. 先进行笛卡尔积

在这里插入图片描述

  1. 指定连接条件
    student.id = score.student_id

在这里插入图片描述

  1. 精简列

在这里插入图片描述

  1. 针对上述结果,再进行 group by 聚合查询

在这里插入图片描述


列出所有同学,每门课程名字,和分数

这包含了三张表(学生表,课程表,分数表)

  1. 先进行笛卡尔积
    三张表的笛卡尔积得到的结果非常多

因此,如果进行数据大的表进行笛卡尔积(多表查询),就会产生大量的临时结果,这个工程是非常消耗时间的
如果多表产需涉及到的表数目比较多的时候,此时,sql 就会非常复杂,可读性也大大降低了

  1. 指定连接条件筛选数据
    三个表,涉及到两个连接条件

在这里插入图片描述

  1. 精简列

在这里插入图片描述

5、内连接

 select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
 select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

在这里插入图片描述

6、外连接

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

在这里插入图片描述

  • 右外连接

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

7、自连接

自连接是指在同一张表连接自身进行查询

  • 显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

要把行转换成列,自己和自己笛卡尔积即可
在这里插入图片描述
在这里插入图片描述
这里根据学生信息筛选
在这里插入图片描述

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

如果想要学生姓名,就可以那上述表和学生表进行笛卡尔积

8、子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询:返回一行记录的子查询

查询与“不想毕业” 同学的同班同学:
在这里插入图片描述


多行子查询:返回多行记录的子查询

查询“语文”或“英文”课程的成绩信息
在这里插入图片描述

  • [NOT] IN关键字
    在这里插入图片描述

9、合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。
使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致
在这里插入图片描述
这里 union 允许把两个不同的表,查询结合合并在一起

在这里插入图片描述
在合并的时候,是会去重的
如果不想去重,使用 union all

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柒柒要开心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值