当前位置:网站首页>数据库学习笔记
数据库学习笔记
2022-07-31 05:09:00 【米兰的小红黑】
一、数据库基础知识
1.1、SQL,db,dbms之间的关系?
sql:
结构化查询语言,是一门标准通用的语言。标准的sql适合于所有的数据库产品
DB:数据库
DBMS:数据库管理系统
DBMS负责执行sql语句,通过执行sql语句操作DB中的数据
1.2、什么是表?
表:table
表:table是数据库的基板组成单元,所有数据都已表哥的形式组织,目的是可读性强
一个表包括行和列:
行:被称为数据/记录(data)
列:被称为字段(column)
每一个字段应该包括那些属性?
字段名、数据类型、相关的约束
1.3、学习mysql主要还是学习通用的SQL 语句,那么SQL语句包括怎删改查,SQL语句怎么分类呢?
DQL(数据查询语言):查询语句,凡是select语句都是DQL
DML(数据操作语言):insert delete update,对表中的数据进行增删改
DDL(数据定义语言):create drop alter,对表结构的增删改
TCL(事务控制语言):commit提交事务,rollback回滚事务。(T:transaction)
DCL(数据控制语言):grant授权、revoke撤销权限等。
1.4、导入数据(后期练习 使用演示的数据)
第一步:登陆mysql数据库管理系统
dos命令窗口:
mysql -uroot -p123456
第二步:查看有哪些数据库
show databases;(这个不是sql语句,属于 mysql的命令)
第三步:创建属于我们自己的数据库
create database bjpowernode数据
第四步: 使用bipowernode数据
use bjpowernode;(这个不是sql语句,属于mysql的命令。)
第五步:
查看当前使用的数据库中有那些表?
show tables;
第六步:初始化数据
mysql ->source sql文件绝对路径
1.5、bipowernode.sql,这个文件以sql结尾,这样的文件被称为“sql脚本”。 什么是sql脚本呢?
当一个文件的扩展名是.sql,并且该文件中编写了大量的sql语句,我们称这样的文件为sql脚本。
注意:直接使用source命令可以执行sql脚本。
sql脚本中的数据量太大时,无法打开,请使用source命令完成初始化。
1.6、mysql常用命令
删除数据库:drop database bjpowernode;
查看表结构:desc dept;
表中的数据 :select * from emp;(查看表中的数据)
mysql> select databases; 查看当前使用的是哪个数据库
mysql> select version(); 查看mysql的版本号
\C 命令结束一条语句
exit 退出mysql
查看创建表的语句:
show create table emp;
二、 sql语句
2.1 简单的查询语句
语法格式:
select 字段名1,字段名2,。。。 from 表名;
注意:
1、 任何一条sql语句以“;” 结尾;
2、sql语句不区分大小写。
查询员工的年薪?(字段可以参与数学运算。)
select ename,sal*12 from emp;

给查看结果的列重命名?
select ename,sal*12 as years from emp;

别名中有中文?
select ename,sal*12 as ‘年薪’ from emp;
select enamel,sal*12 '年薪' from emp;

注意:
1、 标准sql语句中要求字符串使用单引号括起来。虽然mysql支持双引号,尽量别用。
2、as 可以省略
查询所有字段?
select *from emp; // 实际开发中不建议使用

2.2 条件查询
语法格式:
select
字段,字段。。。
from
表名
where
条件;
执行顺序:先from,然后where,最后select
查询工资等于5000的员工姓名?
select ename from emp where sal = 5000;

查询 SMITH的工资:
select sal from emp where ename = 'SMITH';

找出工资高于3000的员工?
select ename,sal from emp where sal > 3000;

找出工资在1100和3000之间的员工,包括1100 和3000之间
select ename ,sal from emp where sal between 1100 and 3000;//between ... and ... 是闭区间[1100 ~3000]

between and 除了可以使用在数字方面之外,还可以使用在字符串方面,左闭右开。
select ename ,sal from emp where ENAME between 'A' and 'C';

找出哪些人没有津贴?
在数据库中NULL不是一个值,代表什么也没有,为空。空不是一个值,不能用等号衡量。必须使用is null 或者is not null
select ename,sal,comm from emp where comm is null;

select ename,sal,comm from emp where comm is not null;

select ename,sal,comm from emp where comm is null or comm = 0;

找出工作岗位是MANAGER和SALESMAN的员工?
select ename,job from emp where job = 'MANAGER'or job = 'SALESMAN';

and 的优先级高于 or
找出薪资大于1000的并且部门编号是20或30的部门员工。
select ename,sal,deptno from emp where sal > 1000 and (deptno = 20 or deptno = 30);

in等同于or:找出工作岗位是MANAGER和SALESMAN的员工?
select ename,job from emp where job = 'MANAGER'or job = 'SALESMAN';
select ename,job from emp where job in ('MANAGER','SALESMAN');

not in :不在这几个值当中。
模糊查询 like:在模糊查询当中,必须掌握两个特殊符号,一个是%,一个是_。%代表任意多个字符,_代表任意一个字符。
找出名字当中含有O的:
select ename from emp where ename like '%o%';

找出第二个字母是A的:
select ename from emp where ename like '_A%';

找出名字中有下划线的:可以使用 / 字符进行转义。
2.3 排序(升序、降序)
按照工资升序,找出员工和薪资?
select ename,sal from emp order by sal;

注意:默认是升序。asc 表示升序,desc表示降序。
按照工资的降序排列,当工资相同时后再按照名字的升序排列
select ename,sal from emp order by sal desc,ename asc;

注意:越靠前的字段越能起到主导作用。只有当前的字段无法完成排序的时候,才会启用后面的字段。
找出工岗位是SALESMAN的员工,并且要求按照薪资的降序排列
select ename,job,sal from emp where job = 'SALESMAN'order by sal desc;

2.4 分组函数
count 计数
sum 求和
avg 平均值
max 最大值
min 最小值
记住:所有的分组函数都是对“某一组”数据进行操作的。
找出工资总和:
select sum(sal) from emp;
找出最高工资;
select max(sal) from emp;
找出最低工资:
select min(sal) from emp;
找出平均工资:
select avg(sal) from emp;
找出总人数:
select count(*) from emp;
分组函数一共5个,分组函数还有另一个名字:多行处理函数。特点:输入多行,最终输出的结果是1行。
分组函数自动忽略NULL。
所有数据库都是这样规定的,只要null参与运算,结果一定是NULL。
ifnull()空处理函数—ifnull(可能为null的数据,被当作什么处理)。
sql语句中有一个语法规则,分组函数不可直接使用在where语句中。
count()和 count(某个具体的字段),他们之间的区别。
count():不是统计某个字段中数据的个数,而是统计总记录条数(和某个字段无关)
count(某个具体的字段):表示统计comm字段中不为NULL的数据总数量。
分组函数也可以组合使用。
2.5 group by 和 having
group by : 按照某个字段或者某些字段进行分组。
having:对分组之后的数据进行再次过滤。
找出每个工作岗位最高薪资:
select ename,max(sal) from emp group by job;

注意:分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。并且任何一个分组函数(count sum avg max min)都是在group by语句结束之后才会执行的。当一条sql语句没有group by的话,整张表的数据会自成一组。
注意:当一个sql语句中出现group by的话,select后面只能跟分组函数和参与分组的字段。
找出每个部门不同工作岗位的最高薪资:
select deptno,job,max(sal) from emp group by deptno,job;

找出每个部门的最高薪资,要求显示薪资大于2900的数据:
select max(sal) from emp where sal > 2900 group by job;
找出每个部门的平均薪资,要求显示薪资大于2900的数据:
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;

2.6 查询结果去重
1、关于查询结果集的去重?
select distinct job from emp;
select ename ,distinct job from emp;
以上的sql语句是错误的。
记住:distinct 智能出现在所有字段的最前面
select distinct deptno ,job from emp;//distinct 对后面的两个字段联合去重
案例:统计岗位的数量?
select count(distinct job) from emp;

2.7 总结一个完整的DQL语句怎么写
Select 5
…
From 1
…
where 2
…
group by 3
…
having 4
…
order by 6
…
3. 连接查询
在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询出最终的结果。
在实际开发中,一般一个业务都会对应多张表,比如:学生和班级,起码两张表。
学生和班级信息存储到一张表中,结果就像上面一样,数据会存在大量的重复,导致数据的冗余。
3.1 连接查询的分类
根据表的连接方式来划分,包括:
内连接:
等值连接
非等值连接
自连接
外连接:
左外链接(左链接)
右外连接(右链接)
全连接(这个不讲,很少用)
3.2 笛卡尔积现象
笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。
关于表的别名:
select e.ename ,d.dname from emp e,dept d;
表的别名有什么好处?
第一:执行效率高
第二:可读性好
3.3 怎么避免笛卡尔积现象?当然是加条件进行过滤。
思考:避免了笛卡尔积现象,会减少记录的匹配次数吗?
不会,次数还是56次。只不过显示的是有效记录。
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
3.4 等值连接
特点:条件是等量关系
案例:查询每个员工的部门名称,要求显示员工名和部门名。
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
语法:
… A (inner) join B on 连接条件 where
3.5 非等值连接
最大的特点是:连接条件中的关系是非等量关系。
案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal;

3.6 自连接
最大的特点是:一张表看做两张表。自己连接自己。
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名
select
a.ename,b.ename
from
emp a
inner join
emp b
on
a.mgr=b.empno;

3.7 外连接
什么是外连接,和内连接有什么区别?
内连接:
假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。
外连接:
假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当附表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。
外连接的分类?
左外链接(左连接):表示左边的这张表是主表
右外链接(右链接):表示右边的这张表是主表
左连接有右链、连接的写法,右链接也会有相应的左连接的写法。
案例:找出每个员工的上级领导?(所有员工都必须查出来)
select
a.ename '员工',b.ename '领导'
from
emp a
left join
emp b
on
a.mgr=b.empno;
案例:找出哪个部门没有员工
select
e.*,d.*
from
emp e
right join
dept d
on
e.deptno=d.deptno
where
e.empno is null;

3.8 三张表的连接
案例:找出每一个员工的部门名称以及工资等级。
select e.ename,e.sal,d.dname from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal;

案例:找出每一个员工的部门名称、工资等级、以及上级领导。
select e.ename,s.grade,d.dname,e1.ename from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp e1 on e.mgr = e1.empno;

4 子查询
4.1 什么是子查询?子查询都可以出现在哪里?
select语句当中嵌套select语句,被嵌套的select语句是子查询。
子查询可以出现在哪里?
select
…(select)
From
…(select)
where
…(select)
4.2 where子句中的子查询
案例:找出高于平均薪资的员工信息。
第一步:找出平均薪资
select avg(sal) from emp;
第二步:where 过滤
select * from emp where sal>2073;
第一步和第二步合并:
select *from emp where sal>(select avg(sal) from emp);
4.3 from后面嵌套子查询
案例:找出每个部门平均薪水的薪水等级
第一步:找出每个部门的平均薪水(按照部门编号分组,求sal的平均值)
select deptno ,avg(sal) as avgsal from emp group by deptno;
第二步:将以上的查询结果当做临时表t,让t表和salgrade s 表连接,条件是:t.avgral between s.losal and s.hisaal;
select
t.*,s.grade
from
(select deptno ,avg(sal) as avgsal from emp group by deptno )t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;

案例:找出每个部门平均的薪水等级。
第一步:找出每个员工的薪水等级。
select e.ename,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hissal;
第二步:基于以上的结果,继续按照deptno分组,求grade平均值。
select
e.deptno,avg(s.grade)
from
emp e join salgrade s
on
e.sal
between s.losal and s.hisal
group by
e.deptno;

4.4 在select后面嵌套子查询
案例:找出每个员工所在的部门名称,要求显示员工名和部门名。
select
e.ename,e.deptno,
(select
d.dname
from
dept d
where
e.deptno=d.deptno
) as dname
from
emp e;
5 union(可以将查询结果集相加)
案例:找出工作岗位是SALSMAN和MANAGER的员工?
第一种:select ename,job from emp where job=‘MANAGER’ or job=‘SALSMAN’;
第二种:select ename,job from emp where job in (‘MANAGER’,‘SALSMAN’);
第三种:UNION
select ename,job from emp where job =‘MANAGER’
UNION
select ename,job from emp where job =‘SALSMAN’;
两张不相干的表中的数据拼接在一起显示。
select ename from emp
union
select dname from dept;
注意:查询的列数要相等。
6 limit
limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制rownum)。limit取结果集中的部分数据,这时它的作用。
6.1、语法机制
limit startIndex,length
startIndex表示起始位置,从0开始,0表示第一条数据
length表示取几个
案例:取出工资前5名的员工(思路:降序取前5个)
select ename,sal from emp order by sal desc;
取前五个:
select ename ,sal from emp order by sal desc limit 0,5
select ename,sal from emp order by sal desc limit 5;
limit是sql语句的最后一个执行环节:
select 5
…
from 1
…
where 2
…
group by 3
…
having 4
…
order by 6
…
limit 7
…
案例:找出工资排名在第四到第九名的员工?
select ename ,sal from emp order by sal desc limit 3,6;
6.2 通用的标准分页sql?
每页显示pageSize条记录:
第pageNo页 (pageNo-1)*pageSize,pageSize
pageSize是什么?是每页显示多少条记录
pageNo是什么?显示第几页
Java代码{
int pageNo=2; //页码是2
int pageSize=10;//每页显示10条
limit (pageNo-1)*pageSize,pageSize
}
7.创建表
建表语句的语法格式:
create table 表名(
字段名1 数据类型
字段名2 数据类型
字段名3 数据类型
....
);
关于MYSQL当中常见的字段数据类型:
- int 整数型(java中的int)
- bigint 长整型(Java中的long)
- float 浮点型(Java中的float double)
- char 定长浮点型(string)
- varchar 可变长字符串(stringbuffer/stringBuilder)
- data 日期类型(对应java.sql. data类型 )
- BLOB 二进制大对象(存储图片、视频等流媒体信息)Binary large OBject (对应Java中的object)
- CLOB 字符大对象(存储较大文本,比如,可以存储4G的字符串) Character Large OBject(对应java中的Object)
char和varchar怎么选择?
在实际的开发中,当某个字段中的数据长度不发生改变的时候,是定长的,例如:性别、生日等都是采用char。当一个字段的数据长度不确定,例如:简介、姓名等都是采用varchar。
8. 插入 insert
insert语句插入数据
语法格式:
insert into 表名(字段名1,字段名2,字段名3…)values(值1,值2,值3)
要求:字段的数量和值的数量相同 ,并且数据类型要对应相同 ,只要能对应上,顺序无所谓。
需要注意的地方: 当一条insert语句执行成功之后,表格当中必然会多一行记录。及时多的这一行记录当中某些字段是NULL,后期也无法在执行insert 语句插入数据了,智能使用update进行更新。
9. 表的复制
语法:
create table 表名 as select 语句; // 将查询结果当做表创建出来。
insert into dept select* from dept; // 将查询结果插入到一张表中?(表中的数据要对应)
10. 修改
update 表名 set 字段名1=值1,字段名2=值2 … where 条件;
注意:没有条件整张表数据全部更新
11. 删除
delete from 表名 where 条件;
注意:没有条件全部删除。
12. 约束
12.1 非空约束
drop table if exists t_user;
create table t_user(
id int ,
username varchar(255) not null,
password varchar(255)
);
insert into t_user(id ,password) values(1,'123');
insert into t_user(id,username,password) values(1,'lisi','123');
12.2 唯一性约束(unique)
唯一约束修饰的字段具有唯一性,不能重复。但可以为NULL。
案例:
drop table if exists t_user;
create table t_user(
id int ,
username varchar(255) unique
);
insert into t_user values(1,'zhangsan');
insert into t_user values(2,'zhagnsan')
案例:给两个列或者多个列添加unique
drop table if exists t_user;
create table t_user(
id int ,
username varchar(255),
email varchar(255),
unique(usercode,username)//多个字段联合起来添加一个约束
);
注意:not null 约束只有列级约束,没有表级约束
12.3 主键约束
*怎么给一张表添加主键约束呢?
drop table if exists t_user;
create table t_user(
id int primary key,
username varchar(255),
email varchar(255)
) ;
主键的特点:不能为NULL,也不能重复。
主键相关的术语?
主键约束:primary key
主键字段:id字段添加primary key之后,id就叫做主键字段
主键值:id字段中的每一个值都是主键值。
主键有什么作用?
-表的设计三范式中有要求,第一范式就要求任何一张表都应该有主键。
-主键的作用:主键值是记录在这张表当中的唯一标识。(就像一个人的身份证号码一样)
主键的分类?
根据主键字段的字段数量来划分:
单一主键 (推荐的,常用的)
复合主键(多个字段联合起来添加一个主键约束)(复合主键不建议使用,因为复合主键违背三范式)
根据主键性质来划分:
自然主键:主键值最好就是一个和业务没有任何关系的自然数。(这种方式是推荐的)
业务主键:主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键(不推荐用)最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一但发生改变的时候,主键值可能也需要随着发生变化,但有的时候没有办法变化,因为变化可能会导致主键值重复
一张表的主键约束只能有一个。(必须记住)
使用表级约束方式定义主键:
drop table if exists t_user;
create table t_user(
id int,
username varchar(255),
primary key(id)
);
mysql 提供主键值 自增:
drop table if exists t_user;
create table t_user (
id int primary key auto-increment, //id字段自动维护一个自增的数字,从1开始,以1递增。
username varchar(255)
);
提示:oracle当中也提供了一个自增机制,叫做:序列(sequence)对象。
12.4 外键约束
外键约束:foreign key
案例:
drop table if exists t_student;
drop table if exists t_class;
Create table t_class(
Cno int,
Cname varcahr(255),
Primary key (cno)
);
Create table t_student(
Sno int,
Sname varchar(255),
Classno int,
Primary key(sno),
Foreign key(classno) references t_class(cno)//加入外键的语句
);
Insert into t_class values(101,’xxxxxxxxxxxxxxxxxxxxxxx’);
Insert into t_class values(101,’yyyyyyyyyyyyyyyyyyyyy’);
Insert into t_student values(1,’zs1’,102);
t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做字表;t_class表叫做父表。
顺序要求:
删除数据的时候,先删除子表,再删除父表。
添加数据的时候,先添加父表,再添加子表。
创建表的时候,先创建父表,再查创建子表。
删除表的时候,先删除子表,再删除父表。
外键值可以为NULL。被引用的字段不一定是主键,但至少具有unique约束。
13 事务
一个事务是一个完整的业务逻辑单元,不可再分。
案例:银行账户转账,从A账户向B账户转账10000.需要执行两条update语句。
Update t_act set balance=balance-10000 where actno=’act-001’;
Update t_act set balance=balance+10000 where actno=’act-002’;
以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。
要想保证以上的两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
事务可以保证多个操作原子性,要么全成功,要么全失败。
13.1 事务的四大特性
- 原子性(Atomicity)
整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。 - 一致性(Consistency)
在事务开始之前与结束之后,数据库都保持一致状态。 - 隔离性(isolation)
一个事务不会影响其他事务的运行。 - 持久性(durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
13.2、和事务相关的语句
只有DML语句(insert delete update)。因为它们这三个语句都适合数据库表当中的“数据”相关的。事务的存在是为了保证数据的完整性,安全性。
13.3、事务的原理
假设一个事儿,需要先执行一条insert,再执行一条update,最后执行一条delete。这个事儿才算完成。
开启事务机制(开始):
执行insert语句–>insert…(这个执行成功之后,把这个执行记录到数据库的操作历史当中,并不会向文件中保存一条数据,不会真正的修改硬盘上的数据。)
执行update语句—>update…(这个执行也是记录一下历史操作,不会真正的修改硬盘上的数据)
执行delete语句—>delete…(这个执行也是记录一下历史操作【记录到缓存】,不会真正的修改硬盘上的数据)
提交事务或者回滚事务(结束)
13.4、事务的特性?
事务包括四大特性:ACID
A:原子性:事务是最小的工作单元,不可再分。
C:一致性:事务必须保证多条DML语句同时成功或者同时失败。
I: 隔离性:事务A与事务B之间具有隔离。
D:持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。
13.5、关于事务之间的隔离性
事务隔离性存在隔离级别,理论上隔离级别包括四个:
- 第一级别:读未提交(read uncommitted)
对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。读未提交存在脏读(dirty read现象):表示读到了脏的数据。 - 第二级别:读已提交(read committed)
对方事务提交之后的数据我方可以读取到。 这种隔离级别解决了:脏读现象没有了。 读已提交存在的问题是:不可重复读。 - 第三级别:可重复读(repeatable read)
这种隔离级别解决了:不可重复读问题。
存在的问题:读取到的数据是幻象。 - 第四级别:串行化读(serializable)
解决了所有问题。效率低,需要事务排队。
Oracle数据库默认的隔离级别是二挡起步:读已提交。(read committed)
Mysql 数据库默认的隔离级别是三档起步:可重复读(repeatable read)。
13.6、演示事务
*mysql事务默认情况下是自动提交的。(什么是自动提交?只要执行任意一条DML语句则提交一次。)怎么关闭自动提交? start transaction;
准备表:
Drop table if exists t_user;
Create table t_user(
Id int primary key auto_increment,
Username varchar(255)
);
演示:mysql中的事务是支持自动提交的,只要执行一条DML,则提交一次。
Insert into t_user(username) values(‘zs’);
- select * from t_user;
- Rollback;
- Select *from t_user;
演示:使用start transaction;关闭自动提交机制。
- Start transaction;
- Insert into t_user(username ) values(‘lisi’);
- Insert into t_user(username ) values(‘wangwu’);
- select * from t_user;
- Rollback;
- select * from t_user;
演示提交
- insert into t_user(username) values(‘rose’);
- Insert into t_user(username) values(‘jack’);
- Select * from t_user;
- Commit; //已经将数据持久到硬盘中了。
- Select * from t_user;
- Rollback;
- Select * from t_user;
13.7、使用两个事务演示以上的隔离级别
第一:演示read uncommitted(使用两个窗口)
- use bjpowernode;
Set global transaction isolation level read uncommitted; //设置事务的全局隔离级别
Select @@global.tx isolation; //查看事务的全局隔离级别
退出窗口,重新开启 - Use bjpowernode;
Start transaction;
Select * from t_user;(table1)
Insert into t_user(username) values(‘smith’);(table2)
Select * from t_user;(可查询到smith)
第二:演示read committed(读已提交)
- Use bjpowernode;
Set global transaction isolation level read committed;
Select @@global.tx_isolation;
Exit; - use bjpowernode;(两个窗口同时使用)
Insert into t_user(name) values(‘test’);(窗口2)
Select * from t_user;(窗口1 未查询到记录)
Commit(窗口2);
Select * from t_user;(窗口1,可查询到结果)
第三:演示repeatable read
- set global transaction isolation level repeatable;
Select @@global.tx_isolation;
Exit; - Use bjpowernode;(两个窗口)
Start transaction;
Delete from t_user;(窗口二)
Commit;(窗口二)
Select *from t_user;(窗口二)
Insert into t_user(username) values(‘test’);(窗口二)
Commit;(窗口二)
Select * from t_user;(窗口二)
Select * from t_user;(窗口一)
第四:演示serializable
- set transaction isolation level serializable;
Select @@global.tx_isolation; - Use bjpowernode;(both two)
Start transaction;(both two)
Select * from t_user;(窗口1)
Insert into t_user(username) values(‘hehe’);(窗口1)
Select * from t_user;(窗口二)
Commit;(窗口一)
Select * from t_user;(窗口二)
14 索引
14.1 什么是索引?有什么用?
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
第一种方式:全表扫描
第二种方式:根据索引检索(效率很高)
索引为什么可以提高检索效率呢?
其实最根本的原理是缩小了扫描的范围。索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中的对象,也需要数据库不断地维护。是有维护成本的。比如,表中的数据也经常被修改这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。添加索引是给某一个字段,或者说某些字段添加索引。
Select ename ,sal from emp where ename=’smith’;
当ename字段上没有添加索引的时候,以上sql语句会进行全表扫描,扫描enamel字段中的所有的值。当enamel字段上添加索引的时候,以上sql语句辉根据索引扫描,快速定位。
14.2、怎么创建索引对象?怎么删除索引对象?
创建索引对象:
Create index 索引名称 on 表名(字段名);
删除索引对象:
Drop index 索引名称 (on 表名);
14.3 什么时候考虑给字段添加索引?(满足什么条件)
- 数据量庞大。(根据客户的需求,根据线上的环境)
- 该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护)
- 该字段经常出现在where字句中。(经常根据哪个字段查询)
注意:主键和具有unique约束的字段自动会添加索引。
14.5、查看sql语句的执行计划:
Explain select ename,sal from emp where sal=5000;
给薪资sal字段添加索引:
Create index emp_sal_index on emp(sal);
Explain select ename,sal from emp where sal=5000;
14.7、索引的实现原理?
索引底层采用的数据结构是:B +Tree
通过B tree 缩小扫描范围,底层索引进行了排序,分析,索引会携带数据在表中的“物理地址”,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。
Select ename from emp where ename=’smith’;
通过索引转换为:
Select ename from emp where 物理地址=0x33;
14.8、索引的分类?
单一索引:给单个字段添加索引
复合索引:给多个字段联合起来添加一个索引
主键索引:主键上会自动添加索引
唯一索引:有unique约束的字段上会自动添加索引
。。。
14.9、索引什么时候失效 ?
Select ename from emp where ename like ‘%A%’;
模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的。
15 视图(view)
15.1、什么是视图
站在不同的角度去看到数据。(同一张表的数据,通过不同的角度去看待)
视图是一种根据查询(也就是SELECT表达式)定义的数据库对象,用于获取想要看到和使用的局部数据。
视图有时也被称为“虚拟表”。
视图可以被用来从常规表(称为“基表”)或其他视图中查询数据。
相对于从基表中直接获取数据,视图有以下好处:
访问数据变得简单
可被用来对不同用户显示不同的表的内容
用来协助适配表的结构以适应前端现有的应用程序
5.2、视图作用
1、视图隐藏了底层的表结构,简化了数据访问操作,客户端不再需要知道底层表的结构及其之间的关系。
2、视图提供了一个统一访问数据的接口。(即可以允许用户通过视图访问数据的安全机制,而不授予用户直接访问底层表的权限)。
3、从而加强了安全性,使用户只能看到视图所显示的数据。
4、视图还可以被嵌套,一个视图中可以嵌套另一个视图。
15.3、怎么创建视图?怎么删除视图?
Create view myview as select empno,ename from emp;
Drop view myview;
注意:只有DQL语句才能以视图对象的方式创建出来。
对视图进行怎删改查,会影响原表数据。(通过视图影响原表数据的,不是直接操作的原表)
15.4、面向视图操作?
Select * from myview;
Create table emp_bak as select * from emp;
Create view myview1 as select empno,ename,sal from emp_bak;
Update myview1 set ename=’hehe’,sal=1 where empno=7369;//通过视图修改原表数据。
Delete from myview1 where empno=7369;//通过视图删除原表数据。
视图示例:
Create view myview2 as select empno a,ename b,sal c from emp_bak;
Select * from myview2;
Insert into myview2(a,b,c) values(…);
15.、视图的作用?
视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,java程序员只对视图对象进行CRUD。
16 、数据库三范式
16.1、什么是设计范式?
设计表的依据。按照这个三范式设计的表不会出现数据冗余。
16.2、三范式都是哪些?
第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。
第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。
提醒:在实际的开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度。
边栏推荐
- 为什么要用Flink,怎么入门使用Flink?
- pytorch中的一维、二维、三维卷积操作
- Unity mobile game performance optimization series: performance tuning for the CPU side
- Redis进阶 - 缓存问题:一致性、穿击、穿透、雪崩、污染等.
- Interview Redis High Reliability | Master-Slave Mode, Sentinel Mode, Cluster Cluster Mode
- mysql5.7.35安装配置教程【超级详细安装教程】
- With MVC, why DDD?
- MySQL window function
- 一文了解大厂的DDD领域驱动设计
- Three oj questions on leetcode
猜你喜欢

精解四大集合框架:List 核心知识总结

账号或密码多次输入错误,进行账号封禁

Minesweeper game (written in c language)

【MySQL8入门到精通】基础篇- Linux系统静默安装MySQL,跨版本升级

【mysql 提高查询效率】Mysql 数据库查询好慢问题解决

mysql5.7.35安装配置教程【超级详细安装教程】

Unity Framework Design Series: How Unity Designs Network Frameworks

MySQL optimization: from ten seconds to three hundred milliseconds

Linux系统安装mysql(rpm方式安装)

Mysql应用安装后找不到my.ini文件
随机推荐
基于web3.0使用钱包Metamask的三方登陆
sql statement - how to query data in another table based on the data in one table
pytorch中的一维、二维、三维卷积操作
【mysql 提高查询效率】Mysql 数据库查询好慢问题解决
Goodbye to the cumbersome Excel, mastering data analysis and processing technology depends on it
Temporal介绍
Linux系统安装mysql(rpm方式安装)
STM32——DMA
matlab abel变换图片处理
sql语句之多表查询
Temporal线上部署
Apache DButils使用注意事项--with modifiers “public“
mysql5.7.35安装配置教程【超级详细安装教程】
[mysql improves query efficiency] Mysql database query is slow to solve the problem
MySQL-如何分库分表?一看就懂
Anaconda配置环境指令
【一起学Rust】Rust学习前准备——注释和格式化输出
Flink sink redis 写入Redis
mysql存储过程
面试官:生成订单30分钟未支付,则自动取消,该怎么实现?