0
点赞
收藏
分享

微信扫一扫

MySQL进阶

一葉_code 2022-03-10 阅读 51



文章目录


  • ​​1.关联查询​​

  • ​​1.1内连接​​
  • ​​1.2自然连接​​
  • ​​1.3外连接​​
  • ​​1.4自连接​​

  • ​​2.子查询​​
  • ​​2.1子查询分类​​
  • ​​3.联合查询​​
  • ​​4.存储程序​​

  • ​​4.1存储过程:输入和输出参数​​
  • ​​4.2存储函数​​
  • ​​4.3触发器​​

  • ​​5.视图​​

  • ​​5.1作用​​
  • ​​5.2视图使用​​

  • ​​6.索引​​

  • ​​6.1性能分析工具​​
  • ​​6.2索引的添加​​
  • ​​6.3InnoDB的索引模型​​

  • ​​7.数据库的设计和优化​​

  • ​​7.1数据库的设计​​
  • ​​7.2数据库优化​​

  • ​​8.数据库的备份和还原​​


1.关联查询


条件获取结果分布于多张表,连接多张表进行查询


1.1内连接


内连接将多张表都出现的记录连接展示在结果集

没有主从表之分,结果与连接顺序无关


# 内连接
select ename,sal,dname,emp.deptno FROM emp,dept where emp.deptno = dept.deptno and empno = 7788;

# inner join ... on...
select * from emp inner join dept on emp.deptno = dept.deptno;

# inner join ...using(字段)
select * from emp inner join dept using(deptno);
* 关联字段名称必须一致
* 将关联字段去重
* 必须使用等值连接

1.2自然连接


自然链接都是等值连接,等值连接不一定是自然链接


select * from emp natural join dept

1.3外连接


以驱动表为基准(left前right后),依次遍历并与附属表简历连接;

如果在附属表中找到匹配的记录就连接并展示;如果找不到则以null填充

存在主从表之分,与连接顺序有关


left [outer] join ... on...;左外连接
right [outer] join ... on...;右外连接
select * from emp left join dept on emp.deptno = dept.deptno;

1.4自连接


自身连接自身


查询员工及其领导的姓名。
select e1.ename,e2.ename from emp e1,emp e2 where e1.mgr = e2.empno;

2.子查询


嵌套查询


2.1子查询分类

# 单行子查询:子查询返回的结果是单行单列
select dname from dept where deptno = (select deptno from emp where empno = 7788);
# 多行子查询: 子查询返回的结果是多行
# 查询工资>2000的员工所在的部门名称
select deptno from emp where deptno in (select distinct deptno from emp where sal > 2000) ;
any / all
=any: 相当于in >any:大于最小值 <any:小于最大值
>all:大于最大值 <all:小于最小值

# 查询工资>2000的员工所在的名称
select dname from dept where deptno in (select DISTINCT deptno FROM emp WHERE sal > 2000);

select dname from dept where exists(
select * from emp WHERE sal > 2000 and emp.deptno = dept.deptno);

in 和 exists之间的区别
1.in先执行子查询,将子查询的结果返回给主查询,由主查询继续检索;exists先执行主查询,将主查询的记录一次交给子查询,在子查询中进行匹配,如果匹配则返回true,并将该主查询的结果展示在结果集,如果返回false则不展示。
2.in必须让查询的条件字段和子查询的结果字段匹配:exists不关心子查询的返回结果。
选择:
1.如果查询的结果分布于多张表,选择关联查询:如果结果分布于一张表,关联查询和子查询都可以使用。
2.查询尽量不要过多的嵌套,理论上说尽可能使用关联查询替代子查询提升性能。
3.尽可能先过滤再关联

3.联合查询

union:去重
union all:不去重
select * FROM emp WHERE deptno = 20
union all
select * FROM emp where sal > 2000;

联合查询多个结果集的字段信息需要一致

4.存储程序


运行于服务器端程序


4.1存储过程:输入和输出参数

# 参数模式:
in:默认,输出参数
out:输出参数
inout:输入输出函数
delimiter//;
create procedure sel_emp(in dno int)
begin
select * from emp where deptno = dno;


end //;

call sel_emp(20);

# 输入员工编号查询名称
delimiter //;
create procedure sel_ename(eno int,out name varchar(20))
begin
select ename into name from emp where empno = eno;

end //;

call sel_ename(7788,@name);
select @name;

# 根据名称获取职位
delimiter //;
create procedure sel_job(inout name_job varchar(20))
begin
select job into name_job from emp where ename = name_job;

end //;

set @v_name = 'SCOTT';
call sel_job(@v_name);
select @v_name;

# 选择结构
delimiter //;
create procedure score(score int)
begin
# 声明变量
declare v_level varchar(20);
if score >= 85 then
set v_level = 'A';
elseif score >= 60 then
set v_level = 'B';
else
set v_level = 'C';
end if;
select v_level;
end //;
# 循环结构
delimiter //;
create procedure calc1()
begin
declare i int;
declare sum int;
set i = 1;
set sum = 0;

lip:loop
if i >100 then
leave lip;
end if;
set sum = sum + i;
set i = i+1;
end loop;
while i<= 100 do
set sum = sum + i;
set i = i+1;
end while;

select sum;

end //;

call calc1();
# repeat ... end repeat
delimiter //;
create procedure calc2()
begin
declare i int;
declare sum int;
set i = 1;
set sum = 0;

repeat
set sum = sum + i;
set i = i+1;
until i >100
end repeat;

select sum;

end //;

call calc2();

4.2存储函数


和存储过程类似,作为sql语句的一部分可以进行调用

允许使用返回值


delimiter //;
create function sel_name(eno int)
returns varchar(20)
DETERMINISTIC
begin
declare v_name varchar(20);
select ename into v_name from emp where empno = eno;
return v_name;
end //;

select sel_name(7788);
存储过程和存储函数区别:
1.关键字不同
2.存储过程是通过输入输出参数实现值传递;输入值通过参数传入,输出值通过返回值实现;
3.存储过程可以被当作独立的执行单元运行;但是函数只能当作sql的部分执行

4.3触发器


时间驱动,不能手动调用,不能传递参数

增删改就是一个事件


delimiter //;
create trigger tri_stu
before delete
on stu for each row
begin
insert into student values(old.sid,old.sname,old.age,old.gender);
end //;

5.视图


称为虚拟表,余姚简历在基表之上,动态实现数据的查询


5.1作用


  • 隐藏细节(铭感字段)
  • 方便实现权限管理
  • 字段的组合,分割等操作

5.2视图使用

# 创建视图(存在条件字段被修改的风险,导致视图中的数据量发生改变)
create view view_emp as select * from emp where deptno = 10;

# 创建视图,不允许修改字段
create view view_emp as select * from emp where deptno = 10 with check option;

其他操作和表的一致

6.索引


提示查询效率创建的数据结构


6.1性能分析工具

  • explain

解释计划任务(解释器)



explain select * from emp;

type:
const > ref > range > all(全表扫描)
  • profiling


sql执行的开销 cpu memory


# 查看是否开启
show variables like '%profiling%';
# 开启profiling
set profiling on;
# 执行sql

# 查看开销
show profiles;

#查看某个sql的开销
show profile cpu,memory for query 281;
  • 慢查询
show variables like '%slow_query%';
show_query_log:查看是否开启慢查询
show_query_log_file:慢查询的日志文件
show_query_time:慢查询的时间

6.2索引的添加


  • 普通索引
    ​create index index_name on tname(colname); drop index index_name on tname; ​
  • 唯一索引

索引列的值必须唯一



​create unique index index_name on tname(colname); alter table tname drop unique; ​​ 主键索引
​alter table tname add constraint PK_NAME primary key(colname); alter table tname drop primary key; ​​ 组合索引

索引字段是多个,通过第一个字段查询走索引,其他字段走全表




create index index_name on tname(col1,col2);

6.3InnoDB的索引模型


  • 主键索引和非主键索引

  • 主键索引:也称为聚簇索引,将记录的信息量总维护在叶子节点上;
  • 非主键索引:也称为二次索引,叶子节点中维护的是主键的值,然后再在主键的索引树中查询记录,称为回表。

  • 添加索引的原则

  • 表的数据较大时适合添加索引
  • 选择高基数列
  • 索引需要维护的,所以不要添加太多索引
  • 增删改较多的表不适合添加索引
  • 索引字段类型和长度尽可能小
  • 尽可能使用主键索引

  • 索引失效的状况

1.索引列不要使用函数以及实现运算
select *from userinfo where power(id,2)=64;
selecy *from userinfo where id+2=10;
2.索引列不要使用前导模糊查询
select *from userinfo where phone like '%3659%';
select *from userinfo where phone like '%2524652%';
3.索引列查询尽量不要使用nullt null
4.使用or可能会导致索引失效(条件中每个字段都必须有一个索引)
select *from userunfo where id=8 or phone='15576426853';

7.数据库的设计和优化

7.1数据库的设计


数据库的基本设施



  • 三大范式

  • 1NF:所有的域是原子性的。
  • 2NF:非主键字段必须和主键字段相关;非主键字段不能与部分主键相关(联合主键)
  • 3NF:非主键必须和主键直接相关而不能间接相关(依赖传递性)

  • 数据库设计的步骤
  • E-R关系图
  • 表之间的关系

  • 一对一:person和recode

  • 外键添加唯一约束
  • 主键做外键

  • 一对多:emp和dept(多的一方添加外键)
  • 多对多:student和course

  • 创建关系表
  • 设计联合主键



7.2数据库优化


  • 设计主键字段类型和长度小
  • 索引字段尽可能使用固定长度的类型(char -->varchar)
  • 查询字段信息时尽可能避免使用limit进行分页查询
  • 避免索引失效的状况
  • 添加缓存–> redis缓存数据
  • 表分区:将整个表的文件物理进行切分(百万)
  • 分区分表(读写分离(主从复制))

8.数据库的备份和还原


  • 备份
    ​mysqldump -uroot -p dbname tname > d:/a.sql ​
  • 还原
    ​mysql -uroot -p < d:/a.sql ​


举报

相关推荐

mysql(进阶)

Mysql进阶

MySQL进阶部分

MySQL进阶(四)

mysql 进阶命令

MySQL进阶查询

mysql进阶学习

0 条评论