视图 View

视图是数据库并不存在的一张表,数据库中的表相关的查询结果在其他地方用到,那就可以考虑将这个结果保存到视图中。

基本语法

  1. create view viewname as
  2. -- 查询语句

image.png
根据上面三张表,可以查询每个同学的相关成绩信息;

  1. select scholar.sid,sname,sage,ssex,cname,score from scholar
  2. inner join sc
  3. on scholar.sid = sc.sid
  4. inner join course
  5. on sc.cid = course.cid;

image.png
如果要将查询出来的结果保存起来; 可以创建视图;

  1. 将上面查询出来的结果保存为视图 students_score;

    1. create view students_score as
    2. -- 查询语句
    3. select scholar.sid,sname,sage,ssex,cname,score from scholar
    4. inner join sc
    5. on scholar.sid = sc.sid
    6. inner join course
    7. on sc.cid = course.cid;

    创建好之后,可以在视图中查看;
    image.png

  2. 查看视图中的内容

    1. select * from students_score;

    image.png

练习

  1. 创建表 users_xxxx; | id | name | job | | —- | —- | —- | | 1 | 王大锤 | 总经理 | | 2 | 张大发 | 经理 | | 3 | 小明 | 员工 | | 4 | 小王 | 员工 | | 5 | 小花 | 员工 | | 6 | 小红 | 员工 |

  2. 创建视图 emps_view_xxxx; 视图中只保存员工信息

  3. 创建视图 manager_view_xxx; 视图中只保存员工,经理信息
  4. 修改视图 emps_view_xxxx中数据, 将Name字段前添加 “张”, 比如原来是小明, 改完后就变为 张小明
  5. 删除manager_view_xxx 中 name 为 小明的数据, 请问可以删除吗?
  1. CREATE table users_zhuyuanying(
  2. `id`int(11)not null auto_increment,
  3. `name`VARCHAR(50)not null,
  4. `job`varchar(10)not NULL,
  5. primary key(`id`)
  6. );
  7. INSERT into `users_zhuyuanying`
  8. (`name`,`job`)
  9. VALUES
  10. ("王大锤","总经理"),("张大发","经理"),("小明","员工"),
  11. ("小王","员工"),("小花","员工"),("小红","员工");
  12. CREATE VIEW emps_view as
  13. select * FROM users_zhuyuanying
  14. WHERE job="员工";
  15. select * FROM viewzhuyuanying;
  16. CREATE VIEW manageview as
  17. select * FROM users_zhuyuanying
  18. WHERE job in ("员工","经理");
  19. select * FROM viewzhuyuanying2;
  20. UPDATE viewzhuyuanying
  21. set NAME="张小王"
  22. WHERE id=4;
  23. UPDATE emps_view
  24. SET name = CONCAT("张",name)
  25. WHERE job = "员工";
  26. SELECT * from emps_view;
  27. delete from manageview
  28. where name="张小明";

视图和表之间的关系

  1. 视图中的数据来源于表;
  2. 视图中数据使用update或者 delete 之后 会将结果同步更新到表中; 其他保存有相同数据的视图也会被更新;

视图的应用场景

  1. 权限管理系统中,举个例子,管理后台中,不同权限的用户登录成功之后看到的结果不一样。可以给不同的权限人员创建不同的视图;比如 经理视图中 可以看到自己手下员工的信息;

存储过程

在批量执行某些sql语句的时候可以创建存储过程。存储过程中可以写其他sql语句。

基本语法

  1. create procedure
  1. 将下面语句封装到存储过程中; ```sql — 声明结束符号 delimiter // — 创建存储过程 insert1w 为存储过程名 CREATE PROCEDURE query_high_score() BEGIN

    1. SELECT sc.Sid,sname,sum(score) from scholar,sc
    2. WHERE scholar.Sid=sc.Sid
    3. GROUP BY sc.Sid
    4. having SUM(score) = (
    5. select sum(score) from sc
    6. GROUP BY sid
    7. order by sum(score) desc
    8. LIMIT 1);

END // — 结束存储过程

— 声明结束符号 改为原来的 ; delimiter ;

CALL query_high_score();

  1. <a name="n9Shh"></a>
  2. ## 练习
  3. [orders.sql](https://www.yuque.com/attachments/yuque/0/2021/sql/87080/1632639809003-63eb5011-43c7-44d5-bedf-cb939a57f773.sql?_lake_card=%7B%22src%22%3A%22https%3A%2F%2Fwww.yuque.com%2Fattachments%2Fyuque%2F0%2F2021%2Fsql%2F87080%2F1632639809003-63eb5011-43c7-44d5-bedf-cb939a57f773.sql%22%2C%22name%22%3A%22orders.sql%22%2C%22size%22%3A2514%2C%22type%22%3A%22%22%2C%22ext%22%3A%22sql%22%2C%22status%22%3A%22done%22%2C%22taskId%22%3A%22u2697a829-934a-498b-98d7-d67663cbdfe%22%2C%22taskType%22%3A%22upload%22%2C%22id%22%3A%22u111582d1%22%2C%22card%22%3A%22file%22%7D)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/87080/1632639226516-434620f5-e3bb-4272-88ec-7580a3f9e2fa.png#clientId=u23526d9f-46d6-4&from=paste&height=474&id=u4d497637&margin=%5Bobject%20Object%5D&name=image.png&originHeight=948&originWidth=1166&originalType=binary&ratio=1&size=387686&status=done&style=none&taskId=u5d461c28-3396-4fb3-9036-b2e636b64ce&width=583)
  4. 1. 查询最近10天的订单信息,并将查询保存为 存储过程,存储过程名字 near10day_xxxxx;
  5. ```sql
  6. -- 1. 查询最近10天的订单信息
  7. select * from orders
  8. where datediff(now(),create_at)<=10;
  9. -- 2. 设置存储过程
  10. -- 声明结束符号
  11. delimiter //
  12. -- 创建存储过程
  13. CREATE PROCEDURE near_10days_orders_xxxx()
  14. BEGIN
  15. select * from orders
  16. where datediff(now(),create_at)<=10;
  17. END
  18. // -- 结束存储过程
  19. -- 声明结束符号 改为原来的 ;
  20. delimiter ;

创建完存储过程之后,使用 关键字 call 来调用即可。

  1. call near_10days_orders_xxxx();
  1. 批量插入1万条数据到数据库中; ```sql

— 声明结束符号 delimiter // — 创建存储过程 insert1w 为存储过程名 CREATE PROCEDURE insert1w() BEGIN DECLARE num int; — 声明变量 num 为int 类型 set num =1; — 设置num 的初始值为 1 WHILE num <=1000 DO insert into users_zhuyuanying (name, job) VALUES (CONCAT(“test”,num),”员工”); set num = num+1; — 更改num的值,比原来增加1

  1. END WHILE;

END // — 结束存储过程

— 声明结束符号 改为原来的 ; delimiter ;

— 调用存储过程 CALL insert1w();

  1. ---
  2. <a name="IzNZH"></a>
  3. # 索引
  4. 当数据量特别大的时候,添加索引可以提高**查询**效率;
  5. <a name="cVsut"></a>
  6. ## 基本语法
  7. ```sql
  8. ALTER TABLE 表名
  9. ADD INDEX `索引的名称`(`字段名`);
  1. 给users表 name添加索引, 索引名为 name_index;
    1. alter table users
    2. add index `name_index`(name);

面试问题

  1. 数据库中有使用过存储过程吗? 怎么用的?

使用过。
场景1:
在做性能测试过程中,需要创建一些测试账号。本质上就是数据库user表中添加多条数据,可以用存储过程来实现。
场景2:
做一些图表类的相关测试时,或者一些常用的多表查询,将这些查询语句定义在存储过程中,使用的时候通过调用存储过程来实现。
不过平时我们在测试的过程中,给我们数据库账号有权限限制,只有查询权限。这些存储过程也是开发写好,我直接去调用。不过,让我写的话。。。。。。。


  1. 视图有有用过吗?跟存储过程有什么区别?

有,用的不多。
view 视图 只能将select 查询结果存到视图中。
procedure 存储过程 可以存储 select,update,delete,insert 这些语句。

view中的内容可以被修改,删除,也可以添加。
存储过程只能使用 call 来调用。


  1. 如何快速的往数据库中添加多条数据?
    1. 使用存储过程。
    2. 使用代码的方式。

  1. 数据库查询速度比较慢解决方案有哪些?
    1. 排查sql查询编写语法是否规范,比如 count(*), count(1);
    2. 添加索引;
    3. 修改数据库配置,或者分库分表;
    4. 实在不行更换服务器配置;

思维导图

Mysql-数据库.svg