MySQL | 数据库的管理和操作【表的增删改查】
系列文章目录
第一章:MySQL | 数据库的管理和操作(基本介绍)
第二章:MySQL | 数据库的基本操作和表的基本操作
第三章:MySQL | 数据库的表的增删改查
文章目录
本节目标
- CRUD : Create, Retrieve,Update,Delete
- 新增数据
- 查询数据
- 修改数据
- 删除数据
- 注释:在SQL中可以使用“–空格+描述”来表示注释说明
CRUD
即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写。
一、新增(Create)
语法:
INSERT[INTO] table_name
[(column[,column]...)]VALUES(value_list)[,(value_list)]...
value_list: value,[,value]...
案例:
insertinto student valuse (1,'张三');
- 这里的个数,类型,顺序和表头结构匹配
- SQL没有字符类型,
‘’
和“”
都可以表示字符串 - 这里数据库在插入的有的时候是报错,这是因为在数据库不做任何修改,默认情况下创建数据库的字符集是
拉丁文
字符集,不能表示中文
- 此时我们要做的事情就是让我们的数据库,字符集和你输入的时候设置生
utf-8
createdatabase test charset utf8;
- 现在就可以了,一般来说,我们的终端是utf8的,但是有的同学是gbk的;
- 其中
utf8
正常保存数据是没事的,带上表情,就有可能出错了,而utf8mb4
是更完整的utf8
指定列插入 + 全列插入
- 插入两条记录,value_list 数量必须和指定列数量及顺序一致
insertinto student (name,gender)values('张三','男');
此时:
values
后面的内容就是和前面的()的内容匹配
- 要想看到结果,就要使用查询语句,
- 可以看到,id是空着的,别的都有,这就是指定列插入
- 这里的这个语句下面详细介绍
select*from student;
多次插入
- 这里也可以一次性插入多条数据,那就是一次插入
insertinto student values(2,'李四','男'),(3,'王五','男');
- 一次插入n个记录,比一次插入一个数据,分n次插入,效率要高
时间日期类型,数据的插入
createtable homework (id int,creatTime datetime);
- 插入时间的时候,是通过特定格式的字符串来表示时间日期的,如
‘2023-02-17 21:25:00’
insertinto homework values(1,'2023-02-17 21:25:00');
- 那么我现在就想把这个时间日期设置成当前时刻,咋办?sql提供了一个特殊的函数,
now()
insertinto homework values(1,now());
二、查询(Retrieve)
全列查找
全列查找(查找整个表的所有行,所有列)
select*from 表名
- 这里面的
*
表示所有的列,这种特殊含义的符号,计算机中叫做【通配符】
- 但是这里执行
select *
操作,肯会非常危险 - 如果数据量就几百几千,就没有什么事,如果数据量有几亿,几十亿
select *
操作就很麻烦了,这个操作会瞬间吃满硬盘带宽和网络带宽,就可能导致其他程序无法使用硬盘或者使用网络
那么怎么办呢?有办法吗?
有的!
当你需要操作的时候,一定要拉上一个人和你一起操作O(∩_∩)O哈哈~
指定列查询
-- 指定列的顺序不需要按定义表的顺序来 select 列名,列名...from 表名;
- 我们需要哪些列就查询哪些列
select name,gender from student;
表达式查询
- 查询过程中,可以做一些简单的运算~~
- 这个是进行
列
和列
之间的运算
createtable exam_result (id int,name varchar(20),chinese decimal(3,1),math decimal(3,1),english decimal(3,1));
insertinto exam_result (id,name,chinese,math,english)values(1,'唐三藏',67,98,56),(2,'孙悟空',87.5,78,77),(3,'猪悟能',88,98.5,90),(4,'曹 孟德',82,84,67),(5,'刘玄德',55.5,85,45),(6,'孙权',70,73,78.5),(7,'宋公明',75,65,30);
- 接下来就看看查询字段为表达式
- 可以在查询的时候,针对分数进行变换;比如让查询的math成绩都在原来的基础上 + 10分;
select name,math +10from exam_result;
- 这个结果都是在原有的分数上 + 10的
- 上述这样的查询,数据库服务器硬盘的数据,是否发生了改变?
- 如果我们再次查询math,此时的结果是 + 10之前的还是 + 10之后的呢?
我们再次操作一下~~
小结一下:
- 我们要要牢记一句话,mysql是一个“客户端-服务器”结构的程序!!!
- 用户在客户端输入的sql,通过请求发送给服务器,服务器解析并执行sql,把查询的结果从硬盘读取出来,通过网络响应还给客户端,客户端把这些数据以
临时表
的形式展现出来 - 这只是在客户端这里显示一下临时表,和服务器那边的硬盘上的表没啥关系
我们还可以查看总成绩,那么怎么查看呢?接着往下看~~
select name,math + chinese + english from exam_result;
表达式查询
是让列和列之间进行运算而不是行和行之间
后面还会学一个
聚合查询
,是行和行之间的运算~~
这就引出了一个查询的时候指定别名~~
指定别名查询
- 指定别名,就相当于是 起了个“小名”更方便的来理解含义
- 我们可以使用
as
关键字来查询 - 下面进行演示:
select name,math + chinese + english as total from exam_result;
- 可以看到,我们查询出来的名字发生了变化~~
- 其中
as
可以省略,但是不建议~~
去重
- 我们可以使用
distinct
关键字进指定列进行去重,把重复的行只保留一个 - 接着看~~
selectdistinct math from exam_result;
- distinct指定多个列的时候,要求这些列的值都相同,才视为重复
查询结果排序
- 使用了
order by
子句,指定某些列进行排序~~,排序可能是升序,也可能是降序 - order by 是可以根据多个列进行排序~~
- 比如说按照数学成绩进行升序排序
select name,math from exam_result orderby math;
- 对于MySQL来说,如果一个sql没有指定order by此时查询的结果的顺序,是
不可预期的
- 代码逻辑中,不能依赖这里的查询顺序的
刚刚是升序排序的,那么怎么降序排序呢?只需要在后面加上
desc
就可以了
select*from exam_result orderby math desc;
- 此处的
desc
是descend
单词的缩写,不是describe
- 还可以使用
asc
表示升序排序,但是省略不写默认就是升序 - 还可以指定多个列来排序,多个列之间使用
,
来分割 ,这个列越靠前,就是越关键的排序依据~~ - 先按照第一列排序,如果第一列的值相同了,再按照第二列排序
select*from exam_result orderby math desc,chinese desc;
条件查询
在查询的时候指定筛选条件
- 需要先描述条件,怎么描述条件呢?
- sql通过一系列的运算符来表示条件~~
比较运算符:
逻辑运算符:
- 通过where子句,再搭配上条件表达式,就可以完成条件查询~~
select*from exam_result where english <60;
- 我们来看一下
- 其中的
where english < 60
相当于针对数据库的表进行遍历,取出每一行数据,把数据代入条件中,看条件是否符合 - 如果是
真
,这个记录就保留,作为结果集的一部分 - 如果是 假,这个记录就pass,下一条继续~~
- 条件查询,可以直接拿两个列进行比较~~
select*from exam_result where chinese > english;
- 这里和上面的
where english < 60
一样,都是取出每一行数据,把数据代入条件中,看条件是否符合
- 条件查询,可以使用表达式来作为条件
select*from exam_result where chinese + english + math <200;
- 这样写是不是不明显,那我们还可以下面这样写
select name,chinese+math+english from exam_result where chinese + english + math <200;
- 这样写是不是更加直观~~
- 还记得吗?有一个
as
的关键词~~ - 那么是不是可以下面这样写?
select name,chinese + math + english as total from exam_result where total <200;
- 可以看到是报错了~~
- 在上面的代码中,写下一个sql,不是从前往后的执行,执行顺序是有特定的规则的执行规则:
- 遍历每一行
- 把这一行代入where的条件中
- 符合条件的结果,再根据select这里指定的列,再进行查询/计算
注意:
此处的total别名不能作为where条件,和当前sql的执行顺序有关,当然,这也是mysql对于语法规定的一部分~~
- 所以只能写成原有的表达式~
select name,chinese + math + english as total from exam_result where chinese + math + english <200;
select*from exam_result where chinese >80and english >80;
select*from exam_result where chinese >80or english >80;
- 如果一个
where
中既存在and
有存在or
,那么它们的优先级是先执行and
后执行or
范围查询
BETWEEN … AND …
- 约定的一个前闭后闭区间(包含两侧边界)
select*from exam_result where chinese >=80and chinese <=90;
- 或者也可以写成下面的代码,这两种写法本质上是一样的~~
select*from exam_result where chinese between80and90;
select*from exam_result where math =58or math =59or math =98or math =99;
- 或者也可以这样写:
select*from exam_result where math in(58,59,98,99);
模糊查询
like
- 模糊匹配,不要求元素完全相同,只要满足一定的规则就可以了
- like 功能比正则表达式简单的多,
只支持两个用法:
- 使用%代表任意0个字符或者N个字符
- 使用_代表任意1个字符
- 列如:
- 查询姓孙的同学
select*from exam_result where name like'孙%';
- 可以看到查询出来了,列如用_来模糊查找:
- 还可以下面这样写~~
like '%孙'
查询结尾的like'%孙%'
查询包含孙的
- mysql效率比较低的,很容易称为性能瓶颈,模糊匹配更是比较低效的写法,如果这里支持的功能更复杂,反而更拖慢数据库的效率~~
- 使用数据库,就算优化出来,也达不到要求,我们的做法是不用数据库,数据都放在内存中搜索~~
NULL 的查询
我们要想查询为空(null)的值,那么怎么查询吗?是下面这样吗?
select*from exam_result where chinese =null;
为什么会出现这样的情况?
- null和其他数值进行运算,结果还是null;
- null结果在条件中,想当于
false
- 所以null = null 结果等于null --> false;
针对这样的问题怎么解决呢?
- 在sql里提供了这样的一个比较相等的
<=>
,使用这个比较相等运算,就可以处理null的比较~ - 可以看到就可以查询成功了
select*from exam_result where chinese <=>null
- 或者也可以下面这样写,对空值进行判定~~
select*from exam_result where chinese isnull;
分页查询
这里所用到的关键字是limit
select*from exam_result limit3;
- 可以看到后面这里加上3,就是只显示3条
- limit还可以搭配offset,声明从那一条开始查询(从0开始计数)
- 下面进行代码演示~~
select*from exam_result limit3offset3;
- 还有一种写法:
limit 3 offset 6
等价于limit 6,3
- 这种写法不太推荐,很容易混淆~~
- limit 这个东西是可以和前面的那些查询搭配使用的~~
列如:查询总分前三名的同学的信息:
- 计算每个同学的总成绩(表达式)
- 按照成绩排序(降序)
- 取前三条记录
代码操作:
select name,chinese + english + math as total from exam_result orderby total desclimit3;
- 注意这里的order by是可以使用别名的
查询基础部分暂时告一段落~~
三、修改(Update)
update 表名 set 列名 = 值...where 条件;
- 我们接着看练习
update exam_result set math =80where name ='孙悟空';
- 我们再进行查看,可以看到已经修改成功了~~
update exam_result set math =60,chinese =70where name ='曹孟德';
select name, chinese + math + english as total from exam_result orderby total desc;
- 首先我们查看有哪些同学是倒数三名的~~
- null在排序的时候,视为最小的值~~
- 然后我们接下来再进行将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
update exam_result set math = math +30orderby chinese + math + english asclimit3;
- 如果要加的的数字超出范围了,就会报错,原来的成绩不会修改
- 我们加上10应该就不会报错了~~
update exam_result set math = math +10orderby chinese + math + english asclimit3;
- 可以看到,已经加成功了~~
- 这里如果要改成两倍的话,就会超出范围,我们就修改成0.5倍~
update exam_result set chinese = chinese /2;
- 我们这里可以查看警告
showwarnings;
- 其中里面的truncated意思就是截断!
- 小数点后位数不够了,只能截断了~
- 这两个成绩已经是截断后的成绩了~~
四、删除(Delete)
delete删除记录(行)
deletefrom 表名 where 条件;
- 删除姓孙的考试成绩
下面进行代码演示:
deletefrom exam_result where name like'孙%';
- 这里就是把条件匹配出来的结果,都删掉了!!
- 那么有同学说表名后面不加条件,会不会里面的内容都会删除?
会的!!!
deletefrom exam_result;
- 可以看到已经全部删除了,这个操作基本相当于删表!!!
所以delete操作也是非常危险的!!!
学习完上面的操作,那么增删改查都是什么呢?
- 增:
insert into 表名...
- 删:
delete from 表名...
- 改:
update 表名...
- 查:
select from 表名...
内容重点总结
- 新增:
-- 单行插入insertinto 表(字段1,..., 字段N)values(value1,...,value N);-- 多行插入insertinto 表(字段1,..., 字段N)values(value1,...),(value2,...),(value3,...);
- 查询
-- 全列查询select*from 表
-- 指定列查询select 字段1,字段2...from 表
-- 查询表达式字段select 字段1+100,字段2+字段3from 表
-- 别名select 字段1 别名1, 字段2 别名2from 表
-- 去重DISTINCTselectdistinct 字段 from 表
-- 排序ORDER BYselect*from 表 orderby 排序字段
-- 条件查询WHERE:-- (1)比较运算符 (2)BETWEEN ... AND ... (3)IN (4)IS NULL (5)LIKE (6)AND (7)OR (8)NOTselect*from 表 where 条件
- 修改
update 表 set 字段1=value1, 字段2=value2...where 条件
- 删除
deletefrom 表 where 条件
好了,数据库的管理和操作【表的增删改查】初阶就到这里结束了,后面我们还有进阶,感谢大家的收看,觉得有用的话三连一下吧~~🌹🌹🌹
版权归原作者 仍然探索未知中 所有, 如有侵权,请联系我们删除。