SQL基础
一、数据库操作
创建数据库
- create database 数据库名称 [character set 字符集 collate 字符集校对规则];
查看数据库
-
查看数据库服务器中的所有数据库:show databases;
-
查看某个数据库的定义信息:show create database 数据库名称:
修改数据库
- alter database 数据库名称 character set 字符集 collate 校对规则;
删除数据库
-
drop database 数据库名称;
其他数据库操作
-
切换数据库:use 数据库名称;
- 查看当前正在使用的数据库:select database();
二、数据库表的操作
字段
字段类型对比
Java | mysql |
---|---|
byte/short/int/long | tinyint/smallint/int/bigint |
float | float |
double | double |
boolean | bit |
char/String | char和varchar |
char和varchar的区别
- char代表是固定长度的字符或字符串。
- 例:定义类型char(8),向这个字段存入字符串hello,那么数据库使用三个空格将其补全。
- varchar代表的是可变长度的字符串。
- 例:定义类型varchar(8),向这个字段存入字符串hello,那么存入到数据库的就是hello。
Date(date/time/datetime/timestamp)
datetime和timestamp区别
- datetime就是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用null存入到数据库中
- timestamp也是既有日期又有时间的日期类型,如果没有向这个字段中存值,数据库使用当前的系统时间存入到数据库中
File(BOLB/TEXT)
- BOLB:存储图片,文件
- TEXT:存储大文本
约束
- 约束作用:保证数据的完整性
- 单表约束分类:
- 主键约束:primary key 主键约束默认就是唯一 非空的
- 唯一约束:unique
- 非空约束:not null
创建表
- create table 表名称(字段名称 字段类型(长度) 约束, 字段名称 字段类型(长度) 约束......)
查看表
- 查看某个数据库的所有表:show tables;
- 查看某个表的结构信息:desc 表名;
删除表
-
drop table 表名;
修改表
-
添加列:alter table 表名 add 列名 类型(长度) 约束
- 修改列类型,长度和约束:alter table 表名 modify 列名 类型(长度) 约束;
- 删除列:alter table 表名 drop 列名;
- 修改列名称:alter table 表名 change 旧列名 新类名 类型(长度) 约束;
- 修改表名:alter table 表名 to 新的表名;
- 修改表的字符集:alter table 表名 character set 字符集;
三、对数据库表的记录进行操作(重点)
添加表的记录
语法:
- 向表中插入某些列:insert into 表名 (列名1,列名2,列名3…) values (值1,值2,值3…)
- 向表中插入所有列:insert into 表名 values (值1,值2,值3…);
注意事项
值的类型与数据库中表列的类型一致。
值的顺序与数据库中表列的顺序一致。
值的最大长度不能超过列设置最大长度。
值的类型是字符串或者是日期类型,使用单引号引起来。
-
直接向数据库中插入中文记录会出现错误!!!
解决方法:
show variables like '%character%'; --查看数据库中与字符集相关参数: 需要将MySQL数据库服务器中的客户端部分的字符集改为gbk。 找到MySQL的安装路径:my.ini文件,修改文件中[client]下的字符集,重启MySQL的服务器
修改表的记录
语法
- update 表名 set 列名=值,列名=值 [where 条件];
注意事项
- 值的类型与列的类型一致。
- 值的最大长度不能超过列设置的最大长度。
- 字符串类型和日期类型添加单引号。
删除表的记录
语法
- delete from 表名 [where 条件];
注意事项
删除表的记录,指的是删除表中的一行记录。
删除如果没有条件,默认是删除表中的所有记录。
-
删除表中的记录有两种做法:
delete from user;
删除所有记录,属于DML语句,一条记录一条记录删除。事务可以作用在DML语句上的
truncate table user;
删除所有记录,属于DDL语句,将表删除,然后重新创建一个结构一样的表。事务不能控制DDL的
查看表的记录(重点)
注意:SFWGHO(是否违规后):S(select)… F(from)…W(where)…G(group by)…H(having)…O(order by);
语法
- select [distinct] * 列名 [[as] 别名] from 表 [条件]; (distinct:不重复)
条件查询
- 使用where子句
- >,<,>=,<=,<>,=
- like:模糊查询
- in:范围查询
- 条件关联:and, or, not
like
可以进行模糊查询,在like子句中可以使用或者%作为占位符。只能代表一个字符,而%可以代表任意个字符。
- like '李_':名字中必须是两个字,而且是姓李的。
- like '李%':名字中姓李的学生,李子后可以是1个或任意个字符。
- like '%四':名字中以四结尾的。
- like '%王%':只要名称中包含这个字就可以。
in
例:查询英语成绩是69,75,89学生的信息
select * from exam where english in (69,75,89);
排序查询
- 使用order by 字段名称 asc/desc;
例1:查询学生信息,并且按照语文成绩倒序排序:
select * from exam order by chinese desc;
例2:查询学生信息,先按照语文成绩进行倒序排序,如果成绩相同再按照英语成绩升序排序
select * from exam order by chinese desc,english asc;
分组统计查询
-
聚合函数使用
- sum()
- max()
- min()
- count()
- avg()
-
分组查询
语法:使用group by 字段名称;
-
where的子句后面不能跟着聚合函数。如果现在使用带有聚合函数的条件过滤(分组后条件过滤)需要使用一个关键字having
select product,sum(price) from orderitem group by product having sum(price) > 5000;
MySQL基础
一、重置MySQL的密码
-
停止MySQL的服务
-
在cmd下启动MySQL服务
-
重新开启cmd的命令行
-
修改root的密码
-
结束mysqld的进程
-
重新启动MySQL的服务
二、数据库的备份
-
打开cmd的命令行窗口
mysqldump -u root -p web_test1 >C:/web_test1.sql
三、数据库的还原
-
第一种还原方式
- 在数据库服务器内部创建数据库:
- 在命令行窗口
-
第二种还原方式
- 在数据库服务器内部创建数据库:
- 切换到该数据库使用source命令还原
四、多表查询(重难点)
1.交叉连接(不常用)
使用关键字cross join
select * from classes cross join student;
不适用关键字cross join关键字
select * from classes,student;
2.内连接
-
显示内连接
select * from classes c inner join student s on c.cid = s.cno;
-
隐式内链接
SELECT * FROM classes c,student s WHERE c.cid = s.cno;
3.外连接
-
左外连接
SELECT * FROM classes c LEFT OUTER JOIN student s ON c.cid = s.cno;
-
右外连接
select * from classes c right outer join student s on c.cid = s.cno;
内外连接的联系
[图片上传失败...(image-29b1f2-1621497027522)]
4.子查询
带in的子查询
查询学生生日在91年之后的班级的信息。
select * from classes where cid in (SELECT cno FROM student WHERE birthday > '1991-01-01');
带exists的子查询
查询学生生日大于91年1月1日,如果记录存在,前面的SQL语句就会执行
select * from classes where exists (SELECT cno FROM student WHERE birthday > '1991-01-01');
带any的子查询
SELECT * FROM classes WHERE cid > ANY (SELECT cno FROM student )
带all的子查询
SELECT * FROM classes WHERE cid > ALL (SELECT cno FROM student)
五、sql练习
查询班级名称,和班级总人数
select c.cname count(*) from classes c, student s where c.cid = s.cno group by c.cname;
查询学生的姓名和学生所选的总课程平均成绩。
SELECT s.sname, AVG(sc.score) FROM student s, stu_cour sc WHERE s.sid = sc.sno GROUP BY s.name;
查询学生的姓名和学生的选课总数,显示选课超过2门学生姓名。
SELECT s.sname, COUNT(*) FROM student s, stu_cour sc WHERE s.sid = sc.sno GROUP BY s.sname HAVING COUNT(*) > 2;
查询平均成绩大于80分的学生的总数。
SELECT COUNT(*) FROM student s WHERE s.sid IN (SELECT sc.sno FROM stu_cour sc GROUP BY s.sid HAVING AVG(sc.score) > 80);
查询学生和平均成绩,但是平均成绩大于01班的任何一个学生的平均成绩。
SELECT s.name,AVG(sc.score) FROM student s, stu_scur sc WHERE s.sid = sc.sno GROUP BY s.sno HAVING AVG(sc.score) > ANY ( AVG(sc.score) FROM student s,stu_cour sc,classes c WHERE s.sid = sc.sno AND c.cid = cs.cno AND c.cname = '01' GROUP BY s.sid);
六、MySQL事务
1.事务的概念
事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全都成功,要么全都失败。
2.事务的特性(ACID)
原子性(Atomicity)
原子性:事务的不可分割,组成事务的各个逻辑单元不可分割。
一致性(Consistent)
一致性:事务执行的前后,数据完整性保持一致。
隔离性(Isalotion)
隔离性:事务执行不应该受到其他事务的干扰,侧重于事物之间。
持久性(Durable)
持久性:事务一旦结束,数据就持久化到数据库中。
原子性、隔离性、持久性都是为了保障一致性而存在的,一致性也是最终的目的。
3.事务的隔离级别
如果不考虑隔离性,引发一些安全问题
如果不考虑隔离性(一个事务执行受到其他的事务的干扰),引发一些安全问题,主要体现在读取数据上:
- 脏读:一个事务读到了另一个事务未提交的数据,导致查询结果不一致
- 不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致多次查询结果不一致。
- 虚读/幻读:一个事务读到了另一个事务已经提交的insert的数据,导致多次查询结果不一致。
解决这些安全问题
设置事务的隔离级别(由上到下,安全性依次提高,性能依次降低)
读未提交(READ UNCOMMITTED)脏读,不可重复读,虚读都有可能发生
读提交 (READ COMMITTED)避免脏读。不可重复读和虚读是有可能发生
可重复读 (REPEATABLE READ)避免脏读、不可重复读,虚读有可能发生。
串行化 (SERIALIZABLE)避免脏读,不可重复读,虚读。
4.演示脏读
开启两个窗口A,B
-
设置A窗口的隔离级别为read uncommitted;
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted; //Mysql的默认隔离级别是REPEATABLE-READ。
-
在A,B两个窗口中开启事务
Mysql中开启事务有两种方式`begin/start transaction`
在执行begin/start transaction命令,它们并不是一个事务的起点,在执行完它们后的第一个sql语句,才表示事务真正的启动 。
-
在B窗口中完成转账的功能:
update account set money = money - 1000 where name= '小张'; update account set money = money + 1000 where name= '小凤'; ***** 事务未提交!!!
-
在A窗口中进行查询
select * from account;
发现A窗口中已经查询到转账成功了!!!已经发生了脏读:一个事务中已经读到了另一个事务未提交的数据。
5.避免脏读,演示不可重复读
开启两个窗口A,B
-
设置A窗口的隔离级别为read committed;
SET SESSION TRANSACTION ISOLATION LEVEL read committed;
-
分别在两个窗口中开启事务:
start transaction;
-
在B窗口中完成转账
update account set money = money - 1000 where name= '小张'; update account set money = money + 1000 where name= '小凤';
没有提交事务
-
在A窗口中进行查询:
select * from account;
发现这个时候没有转账成功!!!(没有查询到另一个事务未提交的数据:说明已经避免了脏读
-
在B窗口中提交事务
commit;
-
在A窗口查询
select * from account;
发现这次的结果已经发生了变化!!!(已经发生不可重复读:一个事务已经读到了另一个事务提交的update的数据,导致多次查询结果不一致。
6.避免不可重复读
分别开启两个窗口A,B
设置A窗口的隔离级别:repeatable read;
在A,B两个窗口中开启事务
在B窗口完成转账
在A窗口中进行查询
在B窗口中提交事务
-
在A窗口中再次查询
发现在一个事务中的多次查询结果是一致!!!(已经避免不可重复读)。
7.演示串行化
开启两个窗口A,B
设置A窗口的隔离级别:serializable
分别在两个窗口中开启事务:
在B窗口中插入一条记录
-
在A窗口中进行查询
发现A窗口已经卡住了(说明事务不允许出现并发,A窗口需要等待B窗口事务执行完成以后,才会执行A窗口的事务。)当B窗口的事务结束(提交或者回滚),那么A窗口马上就会出现结果。