前言
在维基百科中,很形象的描述了数据库~
数据库,简而言之可以当作一个电子化的文件柜,是一个存储电子文件的处所,用户可以对文件中的数据进行新增,截取,更新,删除等操作.所谓”数据库”是以一定方式存储在一起,能与多个用户共享,具有尽可能小的冗余度,与应用程序彼此独立的数据集合.可见数据库就像一个电子的集合柜,他可以将我们需要存放的信息像日常生活中存储商品一样按照一定的规则分门别类的存放起来以便于我们日后的存取使用,大大的提高了我们使用信息的便利程度
为什么要有数据库?
那么,我们为什么要用这个电子的存储柜呢,我们的信息直接存储到文件夹,硬盘,甚至U盘中不就行了吗.这里概括一些数据相较于文件存储的优越性
1.将数据存储在数据库中会更加的安全,不存在被恶意删除的情况
2.文本文件不适合存储大数据
3.数据库可以更加方便数据检索
4.数据库可以按照要求批量处理数据
5.文件数据不利于查询管理
因为以上需求,数据库应用而生
一些主流的数据库
现在常见的数据库大致有如下这些
SQL Sever: 微软的产品,一般用于管理中,大型的项目
Oracle: 甲骨文的产品,合适于大型项目
MySQL: 也属于甲骨文,但适合我们所做的小中型项目,属于关系型数据库,他的所有数据都是按照行列关系存储的
PostgreSQL: 加州大学伯克利分校自己写的一个数据库,完全开源,免费,其实他就是防范MySQL收费或者不开源的迹象
SQLite: 轻量型数据库,例如我们的手机中就嵌入了这个数据库,我们的联系人什么的就是在这个数据库中存放的.这个数据库可以嵌入到程序中使用,这个数据库是用C语言写的
H2:是java编程的嵌入式数据库
数据库的基本使用
连接服务器
1 | mysql -h 127.0.0.1 -p 3306 -u root -p |
如果这里省略了-h 127.0.0.1默认是连接本地
如果这里省略了-p 3306 默认是连接3306端口号
服务器管理
win+r输入services.msc打开服务管理器,找到MySQL57可以通过左侧按钮来控制数据库服务的开启或者关闭
服务器,数据库,表的关系
所谓服务器其实就是一个数据库管理系统程序,这个管理程序可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库
为保存应用中实体的数据.一般会在数据库中创建多个表,以保存程序中实体的数据
他们之间的关系如下图所示
具体使用
创建一个数据库
应当注意的是操作语句的结尾都有一个分号1
create database school;
使用数据库
只有指定了要使用的数据库才能对这个数据库进行相应的操作1
use school;
创建数据库表
1 | create table student(id int,name varchar(10),gender varchar(2)); |
表中插入数据
1 | insert into student (id,name,gender) values (1,'张三','男'); |
查询表中的数据
1 | select * from student; |
查询后我们可以看到数据都是逻辑存储的,即采用的都是行列的关系存储
MySQL架构
MySQL是一个可移植的数据库,几乎能在当前所有的操作系统上运行,各种系统在底层实习方面各有不同,但是MySQL基本上能保证在各个平台上的物理体系结构的一致性(如下图)
SQL分类
DDL数据定义语言,用来维护存储数据的结构
代表指令:create,drop,alter
DML数据操作语言,用来对数据进行操作
代表指令:insert,delete,update
DCL数据控制语言,主要负责权限管理和事务
代表指令:grant,revoke,commit
存储引擎
存储引擎是:数据库管理系统如何存储数据,如何为存储的书库建立索引和如何更新,查询数据等技术的实现方法
MySQL的核心就是插件式存储引擎,支持多种存储引擎1
show engines;
查看存储引擎
我们需要着重了解MyISAM,Mernory,InnoDB这三个存储引擎
库的操作
创建数据库
创建一个使用utf字符集,并带校对规则的db3数据库,创建时使用判断语句判断是否有重名数据库1
create database if not exists db1 charset=utf8 collate utf8_general_ci;
创建完成后查看数据库是否创建完成
字符集和校验规则
查看系统默认字符集以及校验规则
1 | show variables like 'character_set_database'; |
也可以使用命令来查看数据库支持的字符集1
show charset;
字符集只要是控制用什么语言.例如我们使用的utf8就可以使用中文
同样,也可以使用命令来查看数据库支持的字符集校验规则1
show collation;
校验规则对数据库的影响
为什么我们要设置校验规则,不同的校验规则对数据库有什么影响呢?
我们分别从查询和对数据库的排序方面来说明校验规则的作用
首先,我们分别使用两种不同的校验规则来创建两个数据库
第一个数据库:
字符区分大小写,校验规则使用区别大小写的utf8_bin校验规则
使用该数据库并插入数据
此时进行查询
此时我们可以看到,查询是区分大小写的,即查询’a’和’A’是有区别的,那如果使用不区别大小写的校验规则呢?
我们进行同样的操作
创建表1
create database if not exists db1 charset=utf8 collate utf8_general_ci;
使用表并插入数据
进行查询
此时发现,当我们查询’a’或者’A’时他会不区分大小的同时出现
再分别对两个数据库的内容进行排序操作
db1(采用不区分大小写的校验规则)
这里名字并没有按照顺序排列
db2(采用区分大小写的校验规则)
此时名字显然是按照顺序排列的
总结:
校验规则的不同会影响我们对数据库的其他操作!
操纵数据库
查看数据库
1 | show databases; |
显示创建语句
1 | show create database 数据库名; |
说明:/!40100 default…./这个不是注释,这里表示mysql版本大于4.01的话就执行此句
数据库修改
数据库修改主要是修改数据库的校验规则和字符集
例如,将上面创建的数据库db2的字符集改为gbk
此时在查看创建语句
数据库删除
删除名为test的数据库1
drop database if exists test;
需要注意的是删除之后的结果:
数据库内部看不到对用的数据库
对应的数据库文件夹被删除,级联删除,里面的数据表全部被删除,并且在垃圾回收站也是找不到的
数据库的备份和恢复
在日常学习中我们可能会不小心删除掉了某个数据库,如果里面有重要的信息那么将会造成一定的损失和麻烦,所以备份数据库并在需要的时候恢复不小心删除的数据据就显的比较重要了.
备份
1 | mysqldump -p3306 -u root -p -B 数据库名 > 数据库备份存储的文件路径 |
例如将数据库db2备份到E:/JAVA/数据库备份
此时就已经将该数据库备份到了指定的路径下
这里需要说明两点
1.此命令是直接在命令行进行操作的,不能进入数据后再操作,他的操作级别等同于链接数据库的操作级别
2.这里的-B是指在备份数据库内容的同时备份该数据库的创建语句
3.此处重定向后的内容并不是路径,而是一个文件,所以不需要我们在文件夹里事先创建好文件,数据库会按照要求为我们自动创建对应的文件夹
当然
我们还可以只备份一个数据库中的某一个或者多个表,具体使用如下
这样就在指定的路径下备份了好了某一张表
还原
还原操作的基本语句1
source 备份数据库的路径;
现在我们将db2删除
删除后执行还原操作
查看后发现删除的数据库又回来了
查看连接情况
这条命令可以查看连接当前数据库的用户有哪些1
show processlist;
此时我的数据库只有我一个用户连接,id 为 9.当还有其他人连接我的数据库时,这里的id就会增加,此时数据库的运行速度可能就会变慢如果是友人恶意连接数据库那么甚至可能会出现不必要的麻烦
此时我们可以用 kill 命令来终结某个连接的用户
例如终结id编号为10的用户1
kill 10;
表的操作
前面我们已经创建了表,接下来将具体规范的说明数据库中表的所有操作
创建表
语法:1
2
3
4
5create table table_name(
field1 datatype,
field1 datatype,
field1 datatype
)character set 字符集 collate 校验规则 engine 存储引擎;
此处
field表示列名
datatype表示列类型
character set字符集,如果没有指定字符集,则以所在数据库的字符集为准
collate校验规则,如果没有指定校验规则,则以所在数据库的校验规则为准
实例:1
2
3
4
5create table student(
id int,
name varchar(20),
hobby varchar(30)
)character set utf8 collate utf8_bin engine MyISAM;
不同的存储引擎,创建出来的表的文件不一样,此处创建表使用的存储引擎是MyISAM,则在数据目录中有三个不同的文件,如下图
.frm的文件中存储的是表结构
.MYD的文件中存储的是表数据
.MYI的文件中存储的是表索引
如果没有指定存储引擎,则默认使用的存储引擎是innoDB,使用innoDB创建的表目录文件中的信息就和MyISAM有所区别
.frm的文件中依然存储的是表结构
.ibd的文件中同时存储了表数据和表索引
这也是innoDB和MyISAM存储引擎的一个区别
查看表结构
所有创建的表都具有一个行列关系,即他的结构,desc命令便是查看表结构的命令1
desc 表名;(等同于 show creat table 表名;)
实例:
查看student表的结构
修改表
在使用某一张表的时候,难免有新的需求,增加,删除,修改都是不可缺少的操作,下面介绍三个常用的表操作,增加一列,删除一列,修改一列
首先先在student表中添加三条记录
查看一下
现在在此表的最后添加一个字段用于保存学生照片路径,并查看此时表的变化
1 | alter table student add assets varchar(100) comment '图片路径' after hobby; |
此时查看表结构会发现在字段处多出了刚刚添加的assets字段
在查看表中内容
此时表的末尾列变为了assets,新的字段对原表中的数据没有影响
修改name,将其长度改为60
1 | alter table student modify name varchar(60); |
此时就将name的长度改为了60,可以存放更长的名字了
删除assets列
一旦删除,对应列数据就全部没了
修改表名为xuesheng
1 | alter table student rename to xuesheng; |
此时在使用student就找不到指定的表了,表的名字已经被改为了xuesheng
此处的to可以省略
将name列修改为xingming
1 | alter table xuesheng change name xingming varchar(60);--->新字段要完整定义 |
从表的结构中可以看到name已经被修改为xingming
删除表
1 | drop table 表名; |
表的约束
在一张表中,真正约束字段的是数据类型,不同的数据类型对字段的长度类型都有明确的限制,但是仅仅依靠数据类型来约束表是远远不够的,例如我们可以随意在表中插入相同的字段等等,这样会让表逻辑十分的混乱不严谨.基于这种情况,为了保证数据的合法性我们便需要一些额外的约束
表的约束有很多,这里介绍如下约束: null/not null,default,comment,zerofill,primary key,auto_increment,unique key
空属性(null/not null)
数据库默认字段基本都是字段为空,但是我们应该尽可能避免字段为空,因为数据为空是无法参与运算的
当创建一个表,将某些属性设定为not null,那么在进行插入的时候就不能在插入空了,否则数据库会报错
默认值(default)
默认值:即在初始化时经常出现的某一个具体的数字,它随着创建产生,一开始就已指定好,在真正需要真是数据的时候,用户可以选择性的使用默认值或者修改
举个栗子:创建一个表,表中三个字段,分别为年龄,性别,名字,年龄默认为男,年龄默认为0,姓名不能为空
结果如下:
我们可以在表结构中看到此时姓名不能为空,性别默认为男,年龄默认为0
此时插入数据,不给年龄和性别赋值,则默认值生效!
列描述
列描述:comment,这个关键字没有实际的含义,他是专门用来描述字段的,和我们平时撸代码时的注释一样,他会根据表创建语句保存,让使用者更加清楚该列的目的
列描述示例:1
2
3
4
5create table t2(
id int default 00000 comment '学号',
name varchar(20) not null comment '姓名',
sex varchar(5) default '男' comment '性别'
);
此时使用desc并看不到我们添加的列描述,因为这个列描述仅仅是保存在表创建语句,我们可以通过查看列创建语句来获取这些注释信息
zerofill
我们再来看一下刚才创建t2表时的创建语句
注意观察 ‘id’ int(11)
这个11到底是什么意思呢,int的大小就是4个字节,那这个11代表着什么?带着疑问往下看
我们向该表中插入两条数据,然后浏览一下
注意红圈处
然后我们改变一下id这一列,对他添加zerofill属性,然后在观察之前红圈的位置1
alter table t3 id id int(5) unsigned zerofill;
之前红圈处的数字前面填满了0,仔细数数,此时id刚好是5位
所以zerofill的作用:如果宽度小于设定的宽度(这里宽度设置的是5),则自动填充0,但要注意的是,这只是显示的结果,在MySQL中实际存储的还是1,这点可以用hex函数来证明
数据库内部存储的还是1和2,只是因为他被zerofill修饰了所以有特定的格式化输出
主键
主键: primary key用来唯一的约束字段里面的数据,不能重复,不能为空,且一张表中只能有一个主键,主键所在列通常是整数类型
创建表的时候直接在字段上指定主键
1 | create table t3 ( |
这样便将id这一列指定了主键属性
查看表结构
此时id的key列显示PRI,证明id列也设置主键属性
当然主键也可以是复合的,即多个字段作为主键
1 | create table t4( |
此时id和course共同作为该表的主键
id和course为复合主键
当表创建号之后,可以再次追加主键
例如给t2表的id列追加主键1
alter table t2 add primary key(id);
主键约束: 主键对应的字段不能重复,一旦重复,操作失败
删除主键
清楚t3表的主键:1
alter table t3 drop primary key;
自增长(auto_increment)
auto_increment:当被此属性修饰的字段不给值时会自动的被系统触发,系统会从当前字段中已经有的最大值进行+1操作得到一个新的值,自增长通常和主键搭配使用作为逻辑主键
需要注意的是:
①任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
②自增长字段必须是整数
③一张表最多只能有一个自增长
范例:
创建一个表使id自增长
插入完成后获取上次插入的auto_increment的值(批量插入的是第一个值)
唯一键(unique key)
唯一键:主键可以起到主键列数据不重复的作用,那如果我们现在需要多列中的数据都不能重复,主键显然是不能解决问题的,这时候便需要使用唯一键
,唯一键可以解决多个字段需要唯一性约束的问题
唯一键的本质和主键差不多,但唯一键可以为空,而且可以多个为空,空字段不做唯一性比较
外键(foreign key)
外键主要是用来在两个表之间建立关联,被外键修饰的表称为从表,另外一个表称为主表,主表中的字段必须被主键或者唯一键约束,定义外键后要求外键列数据必须在主表主键列出现或者为null
例题如图:
接下来我们对上面的事例图进行设计:
一.创建主键表1
2
3
4create table myclass(
id int primary key,
name varchar(30) not null comment '班级名'
);
二.创建从表1
2
3
4
5
6create table stu(
id int primary key,
name varchar(20) not null comment '学生名',
classid int,
foreign key (classid) references myclass(id)
);
三.插入数据
1.正常插入数据:
2.错误插入:插入一个班级为30的学生,因为没有这个班,所以插入失败
3.插入一个还没有分配班级的学生1
insert into stu values(102,'赵四',null);
表的增删查改(CRUD)
CRUD是增删查改四个单词的首字母:Create,Delete,Retrieve,Update
Create(增)
前面我们已经用到了很多的表的增加操作,在这里更加规范的总结一下
创建一个表
要求:id设置为主键且子增长,学号不能重复出现也不能为空,姓名不能为空,qq号码可以为空1
2
3
4
5
6create table students(
id int unsigned primary key auto_increment,
sn int not null unique key comment '学号',
name varchar(20) not null comment '姓名',
qq varchar(12) comment 'qq号码'
);
单行数据+全列插入
两次插入两行数据1
2insert into students (id,sn,name,qq) values (100,1000,'吕布',10000);
insert into students (id,sn,name,qq) values (101,1001,'子龙',20000);
这里需要注意一点!
在我们创建表的时候qq的类型给的是varchar,但是在我们进行插入的时候我们直接按照int类型的方式插入了,并且没有报错插入成功,这是因为数据库内部自动替我们做了转换,为了严谨,我们应该都写成规范的字符串类型的插入形式
查看一下:
多行数据+全列插入
一次插入两行数据1
2
3insert into students (id,sn,name,qq) values
(102,1002,'典韦','30000'),
(103,1003,'关羽','40000');
符合要求则插入,否则更新
在本例中,我们同时设置了主键和唯一键,这也就意味着如果有信息的重复插入,主键和唯一键是会进行报错的,插入也会失败,先来看下这种情况1
insert into students (id,sn,name) values (103,1004,'马超');
主键冲突报错1
insert into students (id,sn,name) values (104,1003,'张飞');
唯一键冲突报错
如上情况便不能正确的插入数据,这里我们便用到了复制键(duplicate key),他的作用是,如果主键或者唯一键没有重复则正常插入,如果主键或者唯一键冲突则更新冲突处并重新插入
我们之前表中的情况:
然后我们插入一条冲突数据:1
2insert into students (id,sn,name) values (100,1000,'马超')
on duplicate key update sn = 1000,name = '马超';
可以看到这条数据的主键是和吕布的主键冲突的,执行这条语句后观察students表
原先冲突处的主键数据被更新插入,吕布被替换掉了,注意红圈处的数字,这里的返回值是有意义的1
2
3-- 0 row affected: 表示有冲突数据,但冲突数据的值和update的值相等
-- 1 row affected: 表示没有冲突数据,数据被插入
-- 2 row affected: 表示有冲突数据,并且数据已经被更新
我们可以通过MySQL函数获取受到影响的数据行数
使用mysql函数时应该注意一个问题:基本上所有的mysql函数反应的都是上一条语句的执行状况,也就是说想要用函数反应某一个语句的状态一定要跟在该语句的后面执行
替换
如果我们冲突数据都用如上语句来优化,那么未必有点麻烦,因为我们看到上面语句中一个属性我们重复的写了两次,这其实是一种冗余操作,我们有更简便的方法来进行冲突键的替换,如下1
2
3
4
5
6
7-- 主键 或者 唯一键 没有冲突,则直接插入;
-- 主键 或者 唯一键 如果冲突,则删除后再插入;
replace into students (sn,name) values (1003,'吕布');
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
Retrieve(查)
在进行查找操作之前我们需要一个便于演示查找操作的成绩表1
2
3
4
5
6
7CREATE TABLE exam_result (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL COMMENT '同学姓名',
yuwen float DEFAULT 0.0 COMMENT '语文成绩',
shuxue float DEFAULT 0.0 COMMENT '数学成绩',
yingyu float DEFAULT 0.0 COMMENT '英语成绩'
);
插入数据:1
2
3
4
5
6
7
8INSERT INTO exam_result (name, yuwen, shuxue, yingyu) VALUES
('唐三藏', 67, 98, 56),
('孙悟空', 87, 78, 77),
('猪悟能', 88, 98, 90),
('曹孟德', 82, 84, 67),
('刘玄德', 55, 85, 45),
('孙权', 70, 73, 78),
('宋公明', 75, 65, 30);
select列查询
全列查询
全列查询:就是我们之前一直使用的 select * from table_name;
但是,在正常的工作学习中不建议使用这种方法,因为有些时候一个表的信息量是十分巨大的,再不清楚表结构和内容的情况下贸然使用这种查询方法,如果所查内容过于巨大,则会造成数据库或者计算机的崩溃
全列查询示范(此时表内容我们清楚,所以可以直接使用全列查询):
指定列查询
指定查询id,name,yuwen这三列1
2-- 查询列的顺序不需要按照定义表的顺序来
select id,name,yuwen from exam_result;
查询字段为表达式
1 | -- 表达式不包含字段 |
1
2-- 表达式包含字段
select id,name,yuwen+10 from exam_result;
和上边第一次查找语文成绩相比所有成绩加了10
表达式也可以包含多个字段,现在将yuwen,shuxue,yingyu加在一起1
select id,name,yuwen+shuxue+yingyu from exam_result;
将查询结果指定别名
去除重复结果
在数学列中id为1和3的数学成绩重复
我们进行去重的操作
where条件查询
查询英语成绩不及格的同学
运用到的比较运算符: <1
select id,name,yingyu from exam_result where yingyu<60;
查询语文成绩在[80,90]分的同学
同时运用比较运算符 >=,<=和逻辑运算符and1
select id,name,yuwen from exam_result where yuwen>=80 and yuwen<=90;
也可以使用运算符 between .. and ..1
select id,name,yuwen from exam_result where yuwen between 80 and 90;
结果相同
查询数学成绩是58或者59或者98的同学
用到逻辑运算符 or1
2-- 使用or进行条件连接
select id,name,shuxue from exam_result where shuxue=58 or shuxue=59 or shuxue=98;
但这样查询在成绩多的时候会很不方便,以下有好的解决方法,使用in条件1
select id,name,shuxue from exam_result where shuxue in (58,59,98);
查询姓孙的同学
1 | -- % 匹配任意多个(包括0个)任意字符 |
这里的关键字like表示一种模糊查找
还有一种查询方式是严格匹配一个字符的
如下图,此时只能查找到孙权同学:
查找总分在200分以下的同学
1 | select name,yuwen+shuxue+yingyu as 总分 from exam_result where yuwen+shuxue+yingyu<200; |
这里需要注意一个问题:我们将yuwen+shuxue+yingyu重命名为了总分,但是在查询时我们是不能直接使用总分作为条件的,这是因为总分只是查询时的一种输出输出格式,真正在表中保存的是没有总分这一列的
查询语文成绩>80并且不姓孙的同学
逻辑运算符and 和 not的结合使用1
select name,yuwen from exam_result where yuwen>80 and name not like '孙%';
查询姓孙的同学和总成绩>200并且语文成绩<数学成绩并且英语成绩>80的同学
1 | select id,name,yuwen,shuxue,yingyu,yuwen+shuxue+yingyu as 总分 from exam_result |
注意这里是有坑的,请注意我们连接两个条件的逻辑关系词是or而不是and..
题目中说的是 条件1和条件2,为什么使用的是or呢?这一定要搞清楚
and 查询的是在and左右两边的条件都必须同时满足的对象
or 的要求是两边的条件如果满足一边就查询一边,两边都满足则同时查询出来
所以显然此处应该使用or,不要被题干字面所迷惑
null的查询
查询qq为空的同学
1 | select name,qq from students where qq is null; |
NULL和NULL的比较,= 和<=>的区别
结果排序(order by)
order by:利用索引的有序性获取有序数据
首先需要了解的是1
2
3-- ASC 为升序
-- DESC 为降序
-- 默认为 ASC
默认排列顺序(升序)
数学成绩按升序排列
需要注意的是如果有谁的成绩是null,那么他一定在第一行,因为null视为比任何值都小,升序出现在最上面
查询同学们各门成绩一次按数学降序,英语升序,语文升序的方式显示
1 | -- 多字段排序,排序优先级随书写顺序 |
由高到低查询同学总分
1 | select name,yuwen+shuxue+yingyu as 总分 from exam_result order by 总分 desc; |
order by子句可以使用列别名
查询姓孙和姓曹的同学的数学成绩,结果按照降序排列
1 | select name,shuxue from exam_result |
筛选分页结果
基本语法:1
2
3
4
5
6
7
8
9
10
11-- 起始下标是 0
-- 从0开始,筛选n条结果
select ... from table_name [where][order by] limit n;
--从s开始,筛选n条结果
select ... from table_name [where][order by] limit s,n;
-- 从s开始,筛选n条结果
select ... from table_name [where][order by] limit s offset n;
-- 这里offset指一个偏移量,代表此次查询从n偏移的位置处开始查找s个
对一张未知的表进行查询时,最好加一条limit 1,避免因为表中数据过大,查询全表数据导致数据库卡死的情况
举个栗子:将exam_result表按id进行分页,每页三条记录,分别显示第1,2,3页1
2-- 查询第一页
select id,name,shuxue,yingyu,yuwen from exam_result order by id limit 3 offset 0;
第二页
第三页
结果不足三个,但不会受影响
偏移量的计算公式:
offset = (PageNumber-1)*PageSize;
Update(改)
将孙权同学的数学成绩改为100分
分别查看孙权同学本来的数学成绩,在将他的数学成绩改为80.
将曹孟德同学的数学改为90,语文改为95
一次更新多个列的操作1
update exam_result set shuxue=90,yuwen=95 where name = '曹孟德';
将总成绩倒数前三的同学数学成绩加上30分
我们先查看一下总分倒数前三的同学是谁1
select name,shuxue+yuwen+yingyu as total from exam_result order by total asc limit 3;
给他们数学都加上30分1
update exam_result set shuxue = shuxue+30 order by yuwen+shuxue+yingyu asc limit 3;
查看添加后的结果:
将所有同学的语文成绩更新为原来的2倍
注意:全表操作要谨慎使用
查看下原表,注意语文列成绩:
将所有人语文成绩更新成2倍1
update exam_result set yuwen=yuwen*2;
再次查看,语文成绩都变成了之前的2倍:
delete(删)
删除数据
删除孙悟空的所有信息
删除整张表
注意:一定要谨慎使用这个操作,不然就真的只剩下跑路了~~!
在我的数据库中有这样一张表:
我们把他删除了,删除后在查看一下
注意一点:此处删除的是表中的全部信息,而不是这个表,删除一个表是用drop操作
截断表(truncate)
截断表可以用于删除表中的所有数据。截断表命令还会回收所有索引的分配页。截断表的执行速度与不带where子句的delete(删除)命令相同,甚至比它还要快。delete(删除)一次删除一行数据,并且将每一行被删除的数据都作为一个事务记录日志;而truncate (截断)表则回收整个数据页,只记录很少的日志项。delete(删除)和truncate(截断)都会回收被数据占用的空间,以及相关的索引。只有表的拥有者可以截断表。
另外,truncate表之后,如果有自动主键的话,会恢复成默认值
插入查询结果
案例:删除表中的重复数据,并将删除数据后的表内容插入到一张新表中,旧表重命名,再将新表命名为旧表名称
1.创建一张测试表
1 | -- 创建新表 |
2.创建一张空表no_duplicate_table结构和duplicate_table一样
1 | create table no_duplicate_table like duplicate_table; |
3.将duplicate_table的去重数据插入到no_duplicate_table
1 | insert into no_duplicate_table select distinct * from duplicate_table; |
4.重命名表名
1 | rename table duplicate_table to old_duplicate_table, |
5.查看最终结果
1 | select * from duplicate_table; |
具体实现过程如下图
聚合函数
count函数:返回查询到的数据的数量
1.统计班级共有多少学生
2.统计班级收集的qq号有多少
sum函数:返回查询到的数据的总和,不是数字没有意义
1.统计数学成绩总分
avg函数:返回查询到的数据的平均值,不是数字没有意义
统计平均分
max函数:返回查询到的数据的最大值,不是数字没有意义
查看英语最高分
min函数:返回查询到的数据的最小值,不是数字没有意义
返回>70分以上的数学最低分
last_insert_id()
查询最后一个id值