黑马程序员 MySQL数据库入门到精通——进阶篇(2)

news2024/11/16 8:33:38

黑马程序员 MySQL数据库入门到精通——进阶篇(2)

  • 1. SQL优化
    • 1.1 插入数据
    • 1.2 主键优化
    • 1.3 order by优化
    • 1.4 group by优化
    • 1.5 limit优化
    • 1.6 count优化
    • 1.7 update优化
  • 2. 视图
    • 2.1 视图-介绍及基本语法
    • 2.2 视图-检查选项(cascaded)
    • 2.3 视图-检查选项(local)
    • 2.4 视图-更新及作用
    • 2.5 视图-案例
  • 3. 存储过程
    • 3.1 存储过程介绍
    • 3.2 存储过程基本语法
    • 3.3 存储过程-变量系统变量
    • 3.4 存储过程变量-用户定义变量
    • 3.5 存储过程变量-局部变量
    • 3.6 存储过程-if判断
    • 3.7 存储过程- 参数(IN,OUT,INOUT)
    • 3.8 存储过程-case
    • 3.9 存储过程- 循环-while
    • 3.10 存储过程循环-repeat
    • 3.11 存储过程-循环-loop
    • 3.12 存储过程游标-cursor
    • 3.13 存储过程条件处理程序-handler
    • 3.14 存储函数
  • 4. 触发器
    • 4.1 触发器-介绍
    • 4.2 触发器-案例1(insert类型)
    • 4.3 触发器-案例2(update类型)
    • 4.4 触发器-案例3(delete类型)
    • 4.5 视图&存储过程&触发器-小结

在这里插入图片描述

在这里插入图片描述

1. SQL优化

1.1 插入数据

insert into tb_ test values(1,'tom');
insert into tb_ test values(2,'cat');
insert into tb_ test values(3,'jerry');
.....
对于这样的数据我们想要插入多条数据,即批量插入应该怎么办?

优化方法

  1. insert into tb_ test values(1,'tom'),(2,'cat'),(3,'jerry');500-1000条比较合适,再多的数据量就不太合适了;
  2. 手动提交事务
start transaction;
insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
insert into tb_test values(4,'Tom'),(5,'Cat'),(6,'Jerry');
insert into tb_test values(7,'Tom'),(8,'Cat'),(9,'Jerry');
commit;
  1. 主键顺序插入
    主键乱序插入: 8 19 21 88 2 4 15 89 5 7 3
    主键顺序插入: 1 2 3 4 5 7 8 9 15 21 88 89

  2. 大批量插入数据
    如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。操作如下:

1,jdTmmKQlwu1,jdTmmKQlwu,jdTmmKQlwu,2020-10-13,1
2,BTJOeWjRiw2,BTJOeWjRiw,BTJOeWjRiw,2020-6-12,2
3,waQTJIIlHI3,waQTJIIlHI,waQTJIIlHI,2020-6-2,0
4,XmeFHwozIo4,XmeFHwozIo,XmeFHwozIo,2020-1-11,1
5,xRrvQSHcZn5,xRrvQSHcZn,xRrvQSHcZn,2020-10-18,2
6,gTDfGFNLEj6,gTDfGFNLEj,gTDfGFNLEj,2020-1-13,0
7,nBETIlVCle7,nBETIlVCle,nBETIlVCle,2020-9-27,1
8,vmePKKZjJU8,vmePKKZjJU,vmePKKZjJU,2020-10-20,2
9,pWjaLhJVaB9,pWjaLhJVaB,pWjaLhJVaB,2020-5-7,0
10,zimgGFPEQe10,zimgGFPEQe,zimgGFPEQe,2020-8-1,1
11,uHpIsEALNp11,uHpIsEALNp,uHpIsEALNp,2020-12-17,2
12,kCfPeCgMjn12,kCfPeCgMjn,kCfPeCgMjn,2020-7-13,0
13,QRkLwosIdM13,QRkLwosIdM,QRkLwosIdM,2020-8-24,1
14,ipsKyeFeJy14,ipsKyeFeJy,ipsKyeFeJy,2020-2-22,2
15,ZRrcPvYDtF15,ZRrcPvYDtF,ZRrcPvYDtF,2020-12-7,0
16,BbLUYWHeTg16,BbLUYWHeTg,BbLUYWHeTg,2020-4-17,1
17,DalMVUpMnk17,DalMVUpMnk,DalMVUpMnk,2020-10-16,2
18,HFtmFtnZPi18,HFtmFtnZPi,HFtmFtnZPi,2020-11-25,0
19,maHoYocalj19,maHoYocalj,maHoYocalj,2020-3-3,1
20,nHKmkDGSeH20,nHKmkDGSeH,nHKmkDGSeH,2020-1-2,2
21,MZZziMtXLH21,MZZziMtXLH,MZZziMtXLH,2020-4-1,0
22,bjUXRogYgF22,bjUXRogYgF,bjUXRogYgF,2020-7-12,1
23,CVgMEIwyGf23,CVgMEIwyGf,CVgMEIwyGf,2020-12-5,2
24,yXVrVLgSmR24,yXVrVLgSmR,yXVrVLgSmR,2020-4-11,0
25,oaFXNzAigC25,oaFXNzAigC,oaFXNzAigC,2020-11-9,1
26,IJrJiutZtD26,IJrJiutZtD,IJrJiutZtD,2020-7-17,2
27,WGwcrfrFOB27,WGwcrfrFOB,WGwcrfrFOB,2020-9-22,0
28,RbCMhegoiU28,RbCMhegoiU,RbCMhegoiU,2020-6-1,1
29,RzRzNPEsQm29,RzRzNPEsQm,RzRzNPEsQm,2020-2-24,2
30,SYzgGoVRwv30,SYzgGoVRwv,SYzgGoVRwv,2020-7-3,0
31,hLuUHxjJhk31,hLuUHxjJhk,hLuUHxjJhk,2020-1-9,1
32,jhUhcVaQkV32,jhUhcVaQkV,jhUhcVaQkV,2020-4-27,2
33,MmbKbOrEpK33,MmbKbOrEpK,MmbKbOrEpK,2020-5-2,0
34,tdEHJZKNBh34,tdEHJZKNBh,tdEHJZKNBh,2020-1-1,1
35,ydXuLXfCdl35,ydXuLXfCdl,ydXuLXfCdl,2020-7-6,2
36,NmFBcmZeAa36,NmFBcmZeAa,NmFBcmZeAa,2020-3-13,0
37,MRTcthPOWV37,MRTcthPOWV,MRTcthPOWV,2020-5-14,1
38,VOXAUgckhi38,VOXAUgckhi,VOXAUgckhi,2020-4-5,2
39,MRmlUaVmKk39,MRmlUaVmKk,MRmlUaVmKk,2020-1-16,0
40,wZWYFhLRpr40,wZWYFhLRpr,wZWYFhLRpr,2020-4-2,1
41,LMrYOftcSY41,LMrYOftcSY,LMrYOftcSY,2020-11-7,2
42,CdragbnGZi42,CdragbnGZi,CdragbnGZi,2020-5-14,0
43,UoxlSsMmRn43,UoxlSsMmRn,UoxlSsMmRn,2020-4-1,1
44,awmXaRMqwr44,awmXaRMqwr,awmXaRMqwr,2020-12-23,2
45,IeDxjlQzeC45,IeDxjlQzeC,IeDxjlQzeC,2020-5-1,0
46,NHNMuLsSrc46,NHNMuLsSrc,NHNMuLsSrc,2020-1-20,1
47,IUHRbNbOzz47,IUHRbNbOzz,IUHRbNbOzz,2020-12-12,2
48,qpcNRHPdEP48,qpcNRHPdEP,qpcNRHPdEP,2020-1-26,0
49,ziHUyxnecB49,ziHUyxnecB,ziHUyxnecB,2020-2-5,1
50,XlcJSJbXuF50,XlcJSJbXuF,XlcJSJbXuF,2020-1-10,2

在这里插入图片描述

#客户端连接服务端时,加.上参数--local-infile
mysql --local -infile -u root -p
#设置全局参数local infile为1, 开启从本地加载文件导入数据的开关
set global local_infile= 1;
#执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/sql1.log' into table 'tb_user' fields terminated by ',' lines terminated by \n';

$ mysql --local-infile -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 8.0.34-0ubuntu0.20.04.1 (Ubuntu)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tb_user            |
+--------------------+
5 rows in set (0.09 sec)

mysql> create database itheima;
Query OK, 1 row affected (0.04 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| itheima            |
| mysql              |
| performance_schema |
| sys                |
| tb_user            |
+--------------------+
6 rows in set (0.01 sec)

mysql> select @@local_infile = 1;
+--------------------+
| @@local_infile = 1 |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)

建立

mysql> set global local_infile =1;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@local_infile = 1;
+--------------------+
| @@local_infile = 1 |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

mysql> use itheima;
Database changed
mysql> CREATE TABLE `tb_user` (
    ->   `id` INT(11) NOT NULL AUTO_INCREMENT,
    ->   `username` VARCHAR(50) NOT NULL,
    ->   `password` VARCHAR(50) NOT NULL,
    ->   `name` VARCHAR(20) NOT NULL,
    ->   `birthday` DATE DEFAULT NULL,
    ->   `sex` CHAR(1) DEFAULT NULL,
    ->   PRIMARY KEY (`id`),
    ->   UNIQUE KEY `unique_user_username` (`username`)
    -> ) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
Query OK, 0 rows affected, 2 warnings (0.21 sec)

mysql> 

mysql> load data local infile '/home/matthew/文档/load_user_100w_sql.sql' into table tb_user fields terminated by ',' lines terminated by '\n';
Query OK, 50 rows affected (0.21 sec)
Records: 50  Deleted: 0  Skipped: 0  Warnings: 0

1.2 主键优化

在上一小节中,我们说主键的顺序插入的性能是高于乱序插入的。为什么???

我们先了解一下:
数据组织方式
🐬🐬🐬在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。

在这里插入图片描述
页分裂
🐬页可以为空、也可以填充一半,也可以填充100%。每个页包含了2-N行数据(如果一行数据多大,会行溢出),根据主键排列。

顺序插入的话:

在这里插入图片描述
在这里插入图片描述
但是要是乱序插入!!!
在这里插入图片描述
在这里插入图片描述

以上过程,找到50%的地方,然后23 47移动到第三个页 然后重新定义指针顺序——页分裂

在这里插入图片描述
那么与之相对应的就是页合并

要是删除的时候,
在这里插入图片描述
🐬当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged) 为删除并且它的空间变得允许被其他记录声明使用。
🐬当页中删除的记录达到MERGE_THRESHOLD ( 默认为页的50%),InnoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。
在这里插入图片描述
在这里插入图片描述

知识小贴士:MERGE_THRESHOLD合并页的阈值,可以自己设置,在创建表或者创建索引时指定。

🐬主键设计原则

  1. 满足业务需求的情况下,尽量降低主键的长度。
  2. 插入数据时,尽量选择顺序插入,选择使用AUTO_ INCREMENT自增主键。
  3. 尽量不要使用UUID做主键或者是其他自然主键,如身份证号。
  4. 业务操作时,避免对主键的修改。

在这里插入图片描述

1.3 order by优化

  1. Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort排序。
  2. Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
mysql> use tb_user;
Database changed
mysql> select * from tb_user;
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
| id | name      | phone       | email                 | profession                  | age  | gender | status | createtime          |
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
|  1 | 吕布      | 17799990000 | lvbu666@163.com       | 软件工程                    |   23 | 1      | 6      | 2001-02-02 00:00:00 |
|  2 | 曹操      | 17799990001 | caocao666@qq.com      | 通讯工程                    |   33 | 1      | 0      | 2001-03-05 00:00:00 |
|  3 | 赵云      | 17799990002 | 17799990@139.com      | 英语                        |   34 | 1      | 2      | 2002-03-02 00:00:00 |
|  4 | 孙悟空    | 17799990003 | 17799990@sina.com     | 工程造价                    |   54 | 1      | 0      | 2001-07-02 00:00:00 |
|  5 | 花木兰    | 17799990004 | 19980729@sina.com     | 软件工程                    |   23 | 2      | 1      | 2001-04-22 00:00:00 |
|  6 | 大乔      | 17799990005 | daqiao666@sina.com    | 舞蹈                        |   22 | 2      | 0      | 2001-02-07 00:00:00 |
|  7 | 露娜      | 17799990006 | luna_love@sina.com    | 应用数学                    |   24 | 2      | 0      | 2001-02-08 00:00:00 |
|  8 | 程咬金    | 17799990007 | chengyaojin@163.com   | 化工                        |   38 | 1      | 5      | 2001-05-23 00:00:00 |
|  9 | 项羽      | 17799990008 | xiaoyu666@qq.com      | 金属材料                    |   43 | 1      | 0      | 2001-09-18 00:00:00 |
| 10 | 白起      | 17799990009 | baiqi666@sina.com     | 机械工程及其自动化          |   27 | 1      | 2      | 2001-08-16 00:00:00 |
| 11 | 韩信      | 17799990010 | hanxin520@163.com     | 无机非金属材料工程          |   27 | 1      | 0      | 2001-06-12 00:00:00 |
| 12 | 荆轲      | 17799990011 | jingke123@163.com     | 会计                        |   29 | 1      | 0      | 2001-05-11 00:00:00 |
| 13 | 兰陵王    | 17799990012 | lanlinwang666@126.com | 工程造价                    |   44 | 1      | 1      | 2001-04-09 00:00:00 |
| 14 | 狂铁      | 17799990013 | kuangtie@sina.com     | 应用数学                    |   43 | 1      | 2      | 2001-04-10 00:00:00 |
| 15 | 貂蝉      | 17799990014 | 84958948374@qq.com    | 软件工程                    |   40 | 2      | 3      | 2001-02-12 00:00:00 |
| 16 | 妲己      | 17799990015 | 2783238293@qq.com     | 软件工程                    |   31 | 2      | 0      | 2001-01-30 00:00:00 |
| 17 | 芈月      | 17799990016 | xiaomin2001@sina.com  | 工业经济                    |   35 | 2      | 0      | 2000-05-03 00:00:00 |
| 18 | 嬴政      | 17799990017 | 8839434342@qq.com     | 化工                        |   38 | 1      | 1      | 2001-08-08 00:00:00 |
| 19 | 狄仁杰    | 17799990018 | jujiamlm8166@163.com  | 国际贸易                    |   30 | 1      | 0      | 2007-03-12 00:00:00 |
| 20 | 安琪拉    | 17799990019 | jdodm1h@126.com       | 城市规划                    |   51 | 2      | 0      | 2001-08-15 00:00:00 |
| 21 | 典韦      | 17799990020 | ycaunanjian@163.com   | 城市规划                    |   52 | 1      | 2      | 2000-04-12 00:00:00 |
| 22 | 廉颇      | 17799990021 | lianpo321@126.com     | 土木工程                    |   19 | 1      | 3      | 2002-07-18 00:00:00 |
| 23 | 后羿      | 17799990022 | altycj2000@139.com    | 城市园林                    |   20 | 1      | 0      | 2002-03-10 00:00:00 |
| 24 | 姜子牙    | 17799990023 | 37483844@qq.com       | 工程造价                    |   29 | 1      | 4      | 2003-05-26 00:00:00 |
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
24 rows in set (0.00 sec)

mysql> show index from tb_userl
    -> ;
ERROR 1146 (42S02): Table 'tb_user.tb_userl' doesn't exist
mysql> show index from tb_user;
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name             | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY              |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          0 | idx_user_phone       |            1 | phone       | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_name        |            1 | name        | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            1 | profession  | A         |          16 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            2 | age         | A         |          22 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            3 | status      | A         |          24 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_email_5          |            1 | email       | A         |          23 |        5 |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
7 rows in set (0.21 sec)

mysql> drop index idx_user_phone on tb_user;
Query OK, 0 rows affected (0.21 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index idx_user_name on tb_user;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from tb_user;
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name             | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY              |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            1 | profession  | A         |          16 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            2 | age         | A         |          22 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            3 | status      | A         |          24 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_email_5          |            1 | email       | A         |          23 |        5 |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
5 rows in set (0.00 sec)
mysql> select id,age,phone from tb_user order by age;
+----+------+-------------+
| id | age  | phone       |
+----+------+-------------+
| 22 |   19 | 17799990021 |
| 23 |   20 | 17799990022 |
|  6 |   22 | 17799990005 |
|  1 |   23 | 17799990000 |
|  5 |   23 | 17799990004 |
|  7 |   24 | 17799990006 |
| 10 |   27 | 17799990009 |
| 11 |   27 | 17799990010 |
| 24 |   29 | 17799990023 |
| 12 |   29 | 17799990011 |
| 19 |   30 | 17799990018 |
| 16 |   31 | 17799990015 |
|  2 |   33 | 17799990001 |
|  3 |   34 | 17799990002 |
| 17 |   35 | 17799990016 |
| 18 |   38 | 17799990017 |
|  8 |   38 | 17799990007 |
| 15 |   40 | 17799990014 |
| 14 |   43 | 17799990013 |
|  9 |   43 | 17799990008 |
| 13 |   44 | 17799990012 |
| 20 |   51 | 17799990019 |
| 21 |   52 | 17799990020 |
|  4 |   54 | 17799990003 |
+----+------+-------------+
24 rows in set (0.01 sec)

走的是全表扫描!!!!

mysql> explain select id,age,phone from tb_user order by age;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select id,age,phone from tb_user order by age,phone;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

#没有创建索引时,根据age, phone进行排序
explain select id,age,phone from tb_user order by age,phone;
#创建索引
create index idx_user_age_phone_aa on tb_user(age,phone);
#创建索引后,根据age, phone进行升序排序
explain select id,age,phone from tb_user order by age,phone;
#创建索引后,根据age, phone进行降序排序
explain select id,age,phone from tb_user order by age desc, phone desc ;

mysql> explain select id,age,phone from tb_user order by age,phone;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.01 sec)

mysql> create index idx_user_age_phone_aa on tb_user(age,phone);
Query OK, 0 rows affected (0.64 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select id,age,phone from tb_user order by age,phone;
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | index | NULL          | idx_user_age_phone_aa | 48      | NULL |   24 |   100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select id,age,phone from tb_user order by age desc, phone desc ;
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+----------------------------------+
| id | select_type | table   | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra                            |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+----------------------------------+
|  1 | SIMPLE      | tb_user | NULL       | index | NULL          | idx_user_age_phone_aa | 48      | NULL |   24 |   100.00 | Backward index scan; Using index |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+----------------------------------+
1 row in set, 1 warning (0.00 sec)

观察下面

mysql> explain select id,age,phone from tb_user order by phone,age ;
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
| id | select_type | table   | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tb_user | NULL       | index | NULL          | idx_user_age_phone_aa | 48      | NULL |   24 |   100.00 | Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

违背了最左前缀法则,所以会出现Using filesort
如果是下面代码呢??

mysql> explain select id,age,phone from tb_user order by age asc, phone desc ;
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
| id | select_type | table   | partitions | type  | possible_keys | key                   | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tb_user | NULL       | index | NULL          | idx_user_age_phone_aa | 48      | NULL |   24 |   100.00 | Using index; Using filesort |
+----+-------------+---------+------------+-------+---------------+-----------------------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

正常来讲是按照正序拍的,但是书写了 desc,所以要多余的排列,所以会出现Using filesort

在这里插入图片描述

那么我想倒着排列怎么办!!!创建索引特殊说明一下即可:

mysql> create index idx_age_pho_ad on tb_user(age asc,phone desc);
Query OK, 0 rows affected (0.16 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from tb_user;
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name              | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY               |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta  |            1 | profession  | A         |          16 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta  |            2 | age         | A         |          22 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta  |            3 | status      | A         |          24 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_email_5           |            1 | email       | A         |          23 |        5 |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_age_phone_aa |            1 | age         | A         |          19 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_age_phone_aa |            2 | phone       | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_age_pho_ad        |            1 | age         | A         |          19 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_age_pho_ad        |            2 | phone       | D         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
9 rows in set (0.18 sec)

🐬这样就不需要用出现Using filesort

mysql> explain select id,age,phone from tb_user order by age asc, phone desc ;
+----+-------------+---------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key            | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | index | NULL          | idx_age_pho_ad | 48      | NULL |   24 |   100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

在这里插入图片描述

在这里插入图片描述

1.4 group by优化

#删除掉目前的联合索idx_user_pro_age_sta;
drop index idx_user_pro_age_sta on tb_user;
#执行分组操作,根据profession字段分组
explain select profession,count(*) from tb_user group by profession;
#创建索引
Create index idx_user_pro_age_sta on tb_user(profession, age,status);
#执行分组操作,根据profession字段分组
explain select profession , count(*) from tb_user group by profession;
#执行分组操作,根据age字段分组
explain select profession , count(*) from tb_user group by age;不满足最左前缀准准
#执行分组操作,根据profession字 段分组
explain select profession , count(*) from tb_user group by profession, age;

mysql> show index from tb_user;
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name              | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY               |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_email_5           |            1 | email       | A         |          23 |        5 |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_age_phone_aa |            1 | age         | A         |          19 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_age_phone_aa |            2 | phone       | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_age_pho_ad        |            1 | age         | A         |          19 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_age_pho_ad        |            2 | phone       | D         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+---------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
6 rows in set (0.00 sec)

mysql> drop index idx_email_5 on tb_user;
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index idx_user_age_phone_aa on tb_user;
Query OK, 0 rows affected (0.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index idx_age_pho_ad on tb_user;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from tb_user;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY  |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.01 sec)

mysql> select profession,count(*) from tb_user group by profession;
+-----------------------------+----------+
| profession                  | count(*) |
+-----------------------------+----------+
| 软件工程                    |        4 |
| 通讯工程                    |        1 |
| 英语                        |        1 |
| 工程造价                    |        3 |
| 舞蹈                        |        1 |
| 应用数学                    |        2 |
| 化工                        |        2 |
| 金属材料                    |        1 |
| 机械工程及其自动化          |        1 |
| 无机非金属材料工程          |        1 |
| 会计                        |        1 |
| 工业经济                    |        1 |
| 国际贸易                    |        1 |
| 城市规划                    |        2 |
| 土木工程                    |        1 |
| 城市园林                    |        1 |
+-----------------------------+----------+
16 rows in set (0.04 sec)
mysql> explain select profession,count(*) from tb_user group by profession;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra           |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
|  1 | SIMPLE      | tb_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using temporary |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
1 row in set, 1 warning (0.00 sec)
mysql> Create index idx_user_pro_age_sta on tb_user(profession, age,status);
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from tb_user;
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table   | Non_unique | Key_name             | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tb_user |          0 | PRIMARY              |            1 | id          | A         |          24 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            1 | profession  | A         |          16 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            2 | age         | A         |          22 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| tb_user |          1 | idx_user_pro_age_sta |            3 | status      | A         |          24 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+---------+------------+----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.00 sec)

mysql> explain select profession,count(*) from tb_user group by profession;
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | index | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | NULL |   24 |   100.00 | Using index |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select profession , count(*) from tb_user group by profession, age;
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tb_user | NULL       | index | idx_user_pro_age_sta | idx_user_pro_age_sta | 54      | NULL |   24 |   100.00 | Using index |
+----+-------------+---------+------------+-------+----------------------+----------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

在这里插入图片描述

1.5 limit优化

🐬对于大数据表的时候,1千万,执行分页操作的话!

mysql> select * from tb_user limit 0,10;
+----+-----------+-------------+---------------------+-----------------------------+------+--------+--------+---------------------+
| id | name      | phone       | email               | profession                  | age  | gender | status | createtime          |
+----+-----------+-------------+---------------------+-----------------------------+------+--------+--------+---------------------+
|  1 | 吕布      | 17799990000 | lvbu666@163.com     | 软件工程                    |   23 | 1      | 6      | 2001-02-02 00:00:00 |
|  2 | 曹操      | 17799990001 | caocao666@qq.com    | 通讯工程                    |   33 | 1      | 0      | 2001-03-05 00:00:00 |
|  3 | 赵云      | 17799990002 | 17799990@139.com    | 英语                        |   34 | 1      | 2      | 2002-03-02 00:00:00 |
|  4 | 孙悟空    | 17799990003 | 17799990@sina.com   | 工程造价                    |   54 | 1      | 0      | 2001-07-02 00:00:00 |
|  5 | 花木兰    | 17799990004 | 19980729@sina.com   | 软件工程                    |   23 | 2      | 1      | 2001-04-22 00:00:00 |
|  6 | 大乔      | 17799990005 | daqiao666@sina.com  | 舞蹈                        |   22 | 2      | 0      | 2001-02-07 00:00:00 |
|  7 | 露娜      | 17799990006 | luna_love@sina.com  | 应用数学                    |   24 | 2      | 0      | 2001-02-08 00:00:00 |
|  8 | 程咬金    | 17799990007 | chengyaojin@163.com | 化工                        |   38 | 1      | 5      | 2001-05-23 00:00:00 |
|  9 | 项羽      | 17799990008 | xiaoyu666@qq.com    | 金属材料                    |   43 | 1      | 0      | 2001-09-18 00:00:00 |
| 10 | 白起      | 17799990009 | baiqi666@sina.com   | 机械工程及其自动化          |   27 | 1      | 2      | 2001-08-16 00:00:00 |
+----+-----------+-------------+---------------------+-----------------------------+------+--------+--------+---------------------+
10 rows in set (0.00 sec)

mysql> select * from tb_user limit 10,10;
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
| id | name      | phone       | email                 | profession                  | age  | gender | status | createtime          |
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
| 11 | 韩信      | 17799990010 | hanxin520@163.com     | 无机非金属材料工程          |   27 | 1      | 0      | 2001-06-12 00:00:00 |
| 12 | 荆轲      | 17799990011 | jingke123@163.com     | 会计                        |   29 | 1      | 0      | 2001-05-11 00:00:00 |
| 13 | 兰陵王    | 17799990012 | lanlinwang666@126.com | 工程造价                    |   44 | 1      | 1      | 2001-04-09 00:00:00 |
| 14 | 狂铁      | 17799990013 | kuangtie@sina.com     | 应用数学                    |   43 | 1      | 2      | 2001-04-10 00:00:00 |
| 15 | 貂蝉      | 17799990014 | 84958948374@qq.com    | 软件工程                    |   40 | 2      | 3      | 2001-02-12 00:00:00 |
| 16 | 妲己      | 17799990015 | 2783238293@qq.com     | 软件工程                    |   31 | 2      | 0      | 2001-01-30 00:00:00 |
| 17 | 芈月      | 17799990016 | xiaomin2001@sina.com  | 工业经济                    |   35 | 2      | 0      | 2000-05-03 00:00:00 |
| 18 | 嬴政      | 17799990017 | 8839434342@qq.com     | 化工                        |   38 | 1      | 1      | 2001-08-08 00:00:00 |
| 19 | 狄仁杰    | 17799990018 | jujiamlm8166@163.com  | 国际贸易                    |   30 | 1      | 0      | 2007-03-12 00:00:00 |
| 20 | 安琪拉    | 17799990019 | jdodm1h@126.com       | 城市规划                    |   51 | 2      | 0      | 2001-08-15 00:00:00 |
+----+-----------+-------------+-----------------------+-----------------------------+------+--------+--------+---------------------+
10 rows in set (0.00 sec)

mysql> 

🐬但是对于1千万的数据时,我要是使用select * from tb_sku limit 9000000,10;,你就等吧!!
越往后时间越长!!!

  • 一个常见又非常头疼的问题就是limit 2000000,10,此时需要MySQL排序前2000010记录,仅仅返回2000000 - 2000010的记录,其他记录丢弃,查询排序的代价非常大。
  • 所以!!!!
    select s.* from tb_sku s, (select id from tb_sku order by id limit 9000000,10) a where s.id = a.id;

在这里插入图片描述

1.6 count优化

🐬 是由存储引擎决定的

🐬对于数据量非常大的表结构的时候。使用count也是非常耗时的select count(*) from tb_sku;

🐬MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高;当然前提是没有where 条件
🐬InnoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

优化思路:自己计数

  • count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是NULL,累计值就加1,否则不加,最后返回累计值。
  • 用法:
    count (*)、count (主键)、count (字段)、count(1)

🐬🐬🐬count的几种用法

  • count (主键)
    • InnoDB引擎会遍历整张表,把每一行的 主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)。
  • count (字段)
    • 没有not null约束: InnoDB引擎会遍历整张表把每一行的字 段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。
    • 有not null约束: InnoDB 引擎会遍历整张表把每一行的字段值都取出来, 返回给服务层,直接按行进行累加。
  • count (1)
    • InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1” 进去,直接按行进行累加。
  • count (*)
    • InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加。

🐬按照效率排序的话,count(字段) < count(主键id) < count(1)count(*),所以尽量使用count(*)

在这里插入图片描述

1.7 update优化

show tables;
select * from course;
update course set name = 'javaEE' where id =1;

更新数据时一定要根据索引字段,要不然不上行锁,而是表锁

update student set no =' 2000100100' where id = 1 ;
update student set no = '2000100105' where name='韦一笑';

🐬InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。

在这里插入图片描述

2. 视图

2.1 视图-介绍及基本语法

介绍
🐬视图(View) 是一种虛拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
🐬通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

准备工作

drop table if exists student;

create table student(
    id   int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '姓名',
    no   varchar(10) null comment '学号'
)comment '学生表';

INSERT INTO student (name, no) VALUES ('黛绮丝', '2000100101');
INSERT INTO student (name, no) VALUES ('谢逊', '2000100102');
INSERT INTO student (name, no) VALUES ('殷天正', '2000100103');
INSERT INTO student (name, no) VALUES ('韦一笑', '2000100104');



create table course(
    id int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '课程名称'
)comment '课程表';


INSERT INTO course (name) VALUES ('Java');
INSERT INTO course (name) VALUES ('PHP');
INSERT INTO course (name) VALUES ('MySQL');
INSERT INTO course (name) VALUES ('Hadoop');




create table student_course(
    id int auto_increment comment '主键' primary key,
    studentid int not null comment '学生ID',
    courseid  int not null comment '课程ID',
    constraint fk_courseid foreign key (courseid) references course (id),
    constraint fk_studentid foreign key (studentid) references student (id)
)comment '学生课程中间表';

INSERT INTO student_course (studentid, courseid) VALUES (1, 1);
INSERT INTO student_course (studentid, courseid) VALUES (1, 2);
INSERT INTO student_course (studentid, courseid) VALUES (1, 3);
INSERT INTO student_course (studentid, courseid) VALUES (2, 2);
INSERT INTO student_course (studentid, courseid) VALUES (2, 3);
INSERT INTO student_course (studentid, courseid) VALUES (3, 4);

创建视图
CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH[CASCADED | LOCAL] CHECK OPTION ]

查询视图
查看创建视图语句: SHOW CREATE VIEW 视图名称;
查看视图数据: SELECT * FROM 视图名称.....;

修改视图
方式一: CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH[CASCADED| LOCAL] CHECK OPTION]
方式二: ALTER VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH[CASCADED | LOCAL] CHECK OPTION]

删除视图
DROP VIEW [F EXISTS]视图名称[视图名称] ...

-- 创建视图
create or replace view stu_v_1 as select id,name from student where id <= 10;

-- 查询视图
show create view stu_v_1;

select * from stu_v_1;

select * from stu_v_1 where id < 3;

-- 修改视图
create or replace view stu_v_1 as select id,name,no from student where id <= 10;

select * from stu_v_1;

alter view stu_v_1 as select id,name from student where id <= 10;

select * from stu_v_1;

-- 删除视图
drop view if exists stu_v_1;

在这里插入图片描述

2.2 视图-检查选项(cascaded)

create or replace view stu_v_1 as select id,name from student where id <= 10 with cascaded check option ;

select * from stu_v_1;

insert into stu_v_1 values(6,'Tom');
insert into stu_v_1 values(30,'Tom12');
insert into stu_v_1 values(17,'Tom22');

在这里插入图片描述
添加检查语句的时候with cascaded check option,(30,Tom)这句话运行报错!!!!
在这里插入图片描述
视图的检查选项

  • 当使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如插入,更新,删除,以使其符合视图的定义。
  • MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。 为了确定检查的范围,mysql提供了两个选项:
    🐬🐬🐬CASCADED和LOCAL,默认值为CASCADED。

在这里插入图片描述

CASCADED不仅要看你当前条件还要看你有所依赖的条件

-- cascaded
create or replace view stu_v_1 as select id,name from student where id <= 15 ;
-- 可以
insert into stu_v_1 values(5,'Tom');
-- 可以
insert into stu_v_1 values(16,'Tom');


create or replace view stu_v_2 as select id,name from stu_v_1 where id >= 10 with cascaded check option ;
-- 可以
insert into stu_v_2 values(13,'Tom');
-- 可以
insert into stu_v_2 values(17,'Tom');


create or replace view stu_v_3 as select id,name from stu_v_2 where id < 20 ;
-- 可以
insert into stu_v_3 values(14,'Tom');

在这里插入图片描述

2.3 视图-检查选项(local)

在这里插入图片描述

-- local
create or replace view stu_v_4 as select id,name from student where id <= 15 with local check option;

-- 可以
insert into stu_v_4 values(5,'Tom');

-- 报错
insert into stu_v_4 values(16,'Tom');


create or replace view stu_v_5 as select id,name from stu_v_4 where id >= 10 with local check option ;
-- 可以
insert into stu_v_5 values(13,'Tom');
-- 报错
insert into stu_v_5 values(17,'Tom');
-- 报错
insert into stu_v_5 values(18,'Tom');

create or replace view stu_v_6 as select id,name from stu_v_5 where id < 20 ;
-- 可以
insert into stu_v_6 values(14,'Tom');

在这里插入图片描述

2.4 视图-更新及作用

视图的更新
要使视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系。如果视图包含以下任何一项,则该视图不可更新:

  1. 聚合函数或窗口函数(SUM()、MIN()、 MAX()、 COUNT()等)
  2. DISTINCT
  3. GROUP BY
  4. HAVING
  5. UNION或者UNION ALL
-- 创建视图, 使用聚合函数
create view stu_v_count as select count(*) from student;

在这里插入图片描述
报错!!!!

insert into stu_v_count values(10);

作用

  • 简单
    • 视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
  • 安全
    • 数据库可以授权,但不能授权到数据库特定行和特定的列上。通过视图用户只能查询和修改他们所能见到的数据
  • 数据独立
    • 视图可帮助用户屏蔽真实表结构变化带来的影响。

在这里插入图片描述

2.5 视图-案例

  1. 为了保证数据库表的安全性。开发人员在操作tb_user表时,只能看到的用户的基本字段,屏蔽手机号和邮箱两个字段。
  2. 查询每个学生所选修的课程 (三张表联查) , 这个功能在很多的业务中都有使用到,为了简化操作,定义一个视图。
create table tb_user(
	id int primary key auto_increment comment '主键',
	name varchar(50) not null comment '用户名',
	phone varchar(11) not null comment '手机号',
	email varchar(100) comment '邮箱',
	profession varchar(11) comment '专业',
	age tinyint unsigned comment '年龄',
	gender char(1) comment '性别 , 1: 男, 2: 女',
	status char(1) comment '状态',
	createtime datetime comment '创建时间'
) comment '系统用户表';


INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('吕布', '17799990000', 'lvbu666@163.com', '软件工程', 23, '1', '6', '2001-02-02 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('曹操', '17799990001', 'caocao666@qq.com', '通讯工程', 33, '1', '0', '2001-03-05 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('赵云', '17799990002', '17799990@139.com', '英语', 34, '1', '2', '2002-03-02 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('孙悟空', '17799990003', '17799990@sina.com', '工程造价', 54, '1', '0', '2001-07-02 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('花木兰', '17799990004', '19980729@sina.com', '软件工程', 23, '2', '1', '2001-04-22 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('大乔', '17799990005', 'daqiao666@sina.com', '舞蹈', 22, '2', '0', '2001-02-07 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('露娜', '17799990006', 'luna_love@sina.com', '应用数学', 24, '2', '0', '2001-02-08 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('程咬金', '17799990007', 'chengyaojin@163.com', '化工', 38, '1', '5', '2001-05-23 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('项羽', '17799990008', 'xiaoyu666@qq.com', '金属材料', 43, '1', '0', '2001-09-18 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('白起', '17799990009', 'baiqi666@sina.com', '机械工程及其自动化', 27, '1', '2', '2001-08-16 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('韩信', '17799990010', 'hanxin520@163.com', '无机非金属材料工程', 27, '1', '0', '2001-06-12 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('荆轲', '17799990011', 'jingke123@163.com', '会计', 29, '1', '0', '2001-05-11 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('兰陵王', '17799990012', 'lanlinwang666@126.com', '工程造价', 44, '1', '1', '2001-04-09 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('狂铁', '17799990013', 'kuangtie@sina.com', '应用数学', 43, '1', '2', '2001-04-10 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('貂蝉', '17799990014', '84958948374@qq.com', '软件工程', 40, '2', '3', '2001-02-12 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('妲己', '17799990015', '2783238293@qq.com', '软件工程', 31, '2', '0', '2001-01-30 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('芈月', '17799990016', 'xiaomin2001@sina.com', '工业经济', 35, '2', '0', '2000-05-03 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('嬴政', '17799990017', '8839434342@qq.com', '化工', 38, '1', '1', '2001-08-08 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('狄仁杰', '17799990018', 'jujiamlm8166@163.com', '国际贸易', 30, '1', '0', '2007-03-12 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('安琪拉', '17799990019', 'jdodm1h@126.com', '城市规划', 51, '2', '0', '2001-08-15 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('典韦', '17799990020', 'ycaunanjian@163.com', '城市规划', 52, '1', '2', '2000-04-12 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('廉颇', '17799990021', 'lianpo321@126.com', '土木工程', 19, '1', '3', '2002-07-18 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('后羿', '17799990022', 'altycj2000@139.com', '城市园林', 20, '1', '0', '2002-03-10 00:00:00');
INSERT INTO itcast.tb_user (name, phone, email, profession, age, gender, status, createtime) VALUES ('姜子牙', '17799990023', '37483844@qq.com', '工程造价', 29, '1', '4', '2003-05-26 00:00:00');
create table student(
    id   int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '姓名',
    no   varchar(10) null comment '学号'
)comment '学生表';

INSERT INTO student (name, no) VALUES ('黛绮丝', '2000100101');
INSERT INTO student (name, no) VALUES ('谢逊', '2000100102');
INSERT INTO student (name, no) VALUES ('殷天正', '2000100103');
INSERT INTO student (name, no) VALUES ('韦一笑', '2000100104');



create table course(
    id int auto_increment comment '主键ID' primary key,
    name varchar(10) null comment '课程名称'
)comment '课程表';


INSERT INTO course (name) VALUES ('Java');
INSERT INTO course (name) VALUES ('PHP');
INSERT INTO course (name) VALUES ('MySQL');
INSERT INTO course (name) VALUES ('Hadoop');




create table student_course(
    id int auto_increment comment '主键' primary key,
    studentid int not null comment '学生ID',
    courseid  int not null comment '课程ID',
    constraint fk_courseid foreign key (courseid) references course (id),
    constraint fk_studentid foreign key (studentid) references student (id)
)comment '学生课程中间表';

INSERT INTO student_course (studentid, courseid) VALUES (1, 1);
INSERT INTO student_course (studentid, courseid) VALUES (1, 2);
INSERT INTO student_course (studentid, courseid) VALUES (1, 3);
INSERT INTO student_course (studentid, courseid) VALUES (2, 2);
INSERT INTO student_course (studentid, courseid) VALUES (2, 3);
INSERT INTO student_course (studentid, courseid) VALUES (3, 4);
-- 案例 :
-- 1. 为了保证数据库表的安全性,开发人员在操作tb_user表时,只能看到的用户的基本字段,屏蔽手机号和邮箱两个字段。
create view tb_user_view as select id,name,profession,age,gender,status,createtime from tb_user;

select * from tb_user_view;

-- 2. 查询每个学生所选修的课程(三张表联查),这个功能在很多的业务中都有使用到,为了简化操作,定义一个视图。

create view tb_stu_course_view as select s.name student_name , s.no student_no , c.name course_name from student s, student_course sc , course c where s.id = sc.studentid and sc.courseid = c.id;

select * from tb_stu_course_view;

在这里插入图片描述

在这里插入图片描述

3. 存储过程

3.1 存储过程介绍

在这里插入图片描述
操作多次数据库就会涉及到多次网络请求,那怎么办啊??????
🐬可以把这些业务量逻辑进行封装!如图 封装成P1之后!我们的应用程序只需要调用P1即可

在这里插入图片描述

介绍
🐬存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。

🐬存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。

特点

  • 封装,复用
  • 可以接收参数,也可以返回数据
  • 减少(应用服务器与数据库)网络交互,效率提升

在这里插入图片描述

3.2 存储过程基本语法

在这里插入图片描述
下面介绍基础语法先用无参的

-- 存储过程基本语法
-- 创建
create procedure p1()
begin
    select count(*) from student;
end;

在这里插入图片描述

-- 调用
call p1();

在这里插入图片描述

-- 查看
select * from information_schema.ROUTINES where ROUTINE_SCHEMA = 'itcast';

show create procedure p1;

-- 删除
drop procedure if exists p1;

在这里插入图片描述
但是在命令行中运行的时候,可能会出现一些问题,因为命令行在遇到分号的时候,就认为我写的这条语句结束了!!!

在这里插入图片描述
🐬注意:在命令行中。执行创建存储过程的SQL时,需要通过关键字delimiter指定SQL语句的结束符。

delimiter $$

-- 存储过程基本语法
-- 创建
create procedure p1()
begin
    select count(*) from student;
end$$

在这里插入图片描述
不想用的时候,改回来就好了

delimiter ;
在这里插入图片描述

3.3 存储过程-变量系统变量

变量有三种🐬🐬🐬:

  • 系统变量
  • 用户定义变量
  • 局部变量

在这里插入图片描述

系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为

  • 全局变量(GLOBAL)
  • 会话变量(SESSION)

在这里插入图片描述

-- 变量: 系统变量
-- 查看系统变量
show session variables ;

show session variables like 'auto%';
show global variables like 'auto%';

select @@global.autocommit;
select @@session.autocommit;


-- 设置系统变量

set global autocommit  = 0;
insert into course(id, name) VALUES (6, 'ES');
commit;

set session autocommit = 1;
select @@global.autocommit;

虽然设置的全局的set global autocommit = 0;,但是你的服务器重启之后,还是默认值!!!!
在这里插入图片描述

3.4 存储过程变量-用户定义变量

用户定义变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@变量名”使用就可以。其作用域为当前连接(当前会话)

  • 两个@ 是系统变量
  • 一个@ 是用户定义变量

在这里插入图片描述
select count(*) into @mycount from tb_user;,把查询语句的结果赋值!!

-- 变量: 用户变量
-- 赋值
set @myname = 'itcast';
set @myage := 10;
set @mygender := '男',@myhobby := 'java';

select @mycolor := 'red';
select count(*) into @mycount from tb_user;

-- 使用
select @myname,@myage,@mygender,@myhobby;

select @mycolor , @mycount;

select @abc;

🐬在mysql中 = ,既是等于号,有事比较是否相等号,没有 ==,所以在用户变量的时候,建议选:=

在这里插入图片描述

在这里插入图片描述

3.5 存储过程变量-局部变量

局部变量是根据需要定义的在局部生效的变量,访问之前,需要DECLARE声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的BEGIN .. END块。
在这里插入图片描述
在这里插入图片描述

🐬🐬🐬变量类型就是数据库字段类型: INT、BIGINT、 CHAR、 VARCHAR、DATE、 TIME等。

-- 变量: 局部变量
-- 声明 - declare
-- 赋值 -
create procedure p2()
begin
    declare stu_count int default 0;
    select count(*) into stu_count from student;
    select stu_count;
end;

call p2();

在这里插入图片描述

3.6 存储过程-if判断

在这里插入图片描述

-- if
-- 根据定义的分数score变量,判定当前分数对应的分数等级。
-- score >= 85分,等级为优秀。
-- score >= 60分 且 score < 85分,等级为及格。
-- score < 60分,等级为不及格。

create procedure p3()
begin
    declare score int default 58;
    declare result varchar(10);

    if score >= 85 then
        set result := '优秀';
    elseif score >= 60 then
        set result := '及格';
    else
        set result := '不及格';
    end if;
    select result;
end;

call p3();

在这里插入图片描述

3.7 存储过程- 参数(IN,OUT,INOUT)

类型含义备注
IN该类参数作为输入,也就是需要调用时传入值默认
OUT该类参数作为输出,也就是该参数可以作为返回值
INOUT既可以作为输入参数,也可以作为输出参数

在这里插入图片描述

在这里插入图片描述

-- in/out/inout参数

-- 根据传入(in)参数score,判定当前分数对应的分数等级,并返回(out)。
-- score >= 85分,等级为优秀。
-- score >= 60分 且 score < 85分,等级为及格。
-- score < 60分,等级为不及格。

create procedure p4(in score int, out result varchar(10))
begin
    if score >= 85 then
        set result := '优秀';
    elseif score >= 60 then
        set result := '及格';
    else
        set result := '不及格';
    end if;
end;

call p4(18, @result);
select @result;


-- 将传入的 200分制的分数,进行换算,换算成百分制 , 然后返回分数 ---> inout
create procedure p5(inout score double)
begin
    set score := score * 0.5;
end;

set @score = 198;
call p5(@score);
select @score;

3.8 存储过程-case

在这里插入图片描述

-- case
-- 根据传入的月份,判定月份所属的季节(要求采用case结构)。
-- 1-3月份,为第一季度
-- 4-6月份,为第二季度
-- 7-9月份,为第三季度
-- 10-12月份,为第四季度

create procedure p6(in month int)
begin
    declare result varchar(10);

    case
        when month >= 1 and month <= 3 then
            set result := '第一季度';
        when month >= 4 and month <= 6 then
            set result := '第二季度';
        when month >= 7 and month <= 9 then
            set result := '第三季度';
        when month >= 10 and month <= 12 then
            set result := '第四季度';
        else
            set result := '非法参数';
    end case ;

    select concat('您输入的月份为: ',month, ', 所属的季度为: ',result);
end;

call  p6(16);

在这里插入图片描述

在这里插入图片描述

3.9 存储过程- 循环-while

在这里插入图片描述

-- while   计算从1累加到n的值,n为传入的参数值。

-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行减1 , 如果n减到0, 则退出循环
create procedure p7(in n int)
begin
    declare total int default 0;

    while n>0 do
         set total := total + n;
         set n := n - 1;
    end while;

    select total;
end;

call p7(100);

在这里插入图片描述

3.10 存储过程循环-repeat

在这里插入图片描述

-- repeat   计算从1累加到n的值,n为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环
create procedure p8(in n int)
begin
    declare total int default 0;

    repeat
        set total := total + n;
        set n := n - 1;
    until  n <= 0
    end repeat;

    select total;
end;

call p8(10);
call p8(100);

在这里插入图片描述

3.11 存储过程-循环-loop

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/d228d4eaefbd43c697a9eaa71833345a.png
#pic_center)

-- loop  计算从1累加到n的值,n为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx

create procedure p9(in n int)
begin
    declare total int default 0;

    sum:loop
        if n<=0 then
            leave sum;
        end if;

        set total := total + n;
        set n := n - 1;
    end loop sum;

    select total;
end;

call p9(100);





-- loop  计算从1到n之间的偶数累加的值,n为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx
-- C. 如果当次累加的数据是奇数, 则直接进入下一次循环. --------> iterate xx

create procedure p10(in n int)
begin
    declare total int default 0;

    sum:loop
        if n<=0 then
            leave sum;
        end if;

        if n%2 = 1 then
            set n := n - 1;
            iterate sum;
        end if;

        set total := total + n;
        set n := n - 1;
    end loop sum;

    select total;
end;

call p10(100);




在这里插入图片描述

3.12 存储过程游标-cursor

-- 通过变量记录查询结果
create procedure p11()
begin
    declare stu_count int default 0;
    select * into stu_count from student;
    select stu_count;
end;

call p11();

在这里插入图片描述
把一张表的数据复制给一个变量,不合适!!!我们之前学的只能是单行单列的

游标CURSOR是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、OPEN、 FETCH 和CLOSE,其语法分别如下。
在这里插入图片描述
变量和条件的申明要在游标之前
在这里插入图片描述

-- 游标
-- 根据传入的参数uage,来查询用户表tb_user中,
-- 所有的用户年龄小于等于uage的用户姓名(name)和专业(profession),
-- 并将用户的姓名和专业插入到所创建的一张新表(id,name,profession)中。

-- 逻辑:
-- A. 声明游标, 存储查询结果集
-- B. 准备: 创建表结构
-- C. 开启游标
-- D. 获取游标中的记录
-- E. 插入数据到新表中
-- F. 关闭游标

create procedure p11(in uage int)
begin
    declare uname varchar(100);
    declare upro varchar(100);
    declare u_cursor cursor for select name,profession from tb_user where age <= uage;
    declare exit handler for SQLSTATE '02000' close u_cursor;

    drop table if exists tb_user_pro;
    create table if not exists tb_user_pro(
        id int primary key auto_increment,
        name varchar(100),
        profession varchar(100)
    );

    open u_cursor;
    while true do
    -- 下行按照顺序来
        fetch u_cursor into uname,upro;
        insert into tb_user_pro values (null, uname, upro);
    end while;
    close u_cursor;

end;


call p11(30);

在这里插入图片描述
但是我的表是有的:
在这里插入图片描述
死循环的原因!!!!

在这里插入图片描述

3.13 存储过程条件处理程序-handler

条件处理程序(Handler) 可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体语法为:
在这里插入图片描述

declare exit handler for SQLSTATE '02000' close u_cursor;
create procedure p12(in uage int)
begin
    declare uname varchar(100);
    declare upro varchar(100);
    declare u_cursor cursor for select name,profession from tb_user where age <= uage;
    declare exit handler for not found close u_cursor;

    drop table if exists tb_user_pro;
    create table if not exists tb_user_pro(
        id int primary key auto_increment,
        name varchar(100),
        profession varchar(100)
    );
    open u_cursor;
    while true do
        fetch u_cursor into uname,upro;
        insert into tb_user_pro values (null, uname, upro);
    end while;
    close u_cursor;
end;

call p12(30);

在这里插入图片描述

3.14 存储函数

存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。具体语法如下:
在这里插入图片描述

-- 存储函数
-- 从1到n的累加

create function fun1(n int)
returns int deterministic
begin
    declare total int default 0;

    while n>0 do
        set total := total + n;
        set n := n - 1;
    end while;

    return total;
end;


select fun1(50);

在这里插入图片描述

4. 触发器

4.1 触发器-介绍

-- 触发器
-- 需求: 通过触发器记录 user 表的数据变更日志(user_logs) , 包含增加, 修改 , 删除 ;

-- 准备工作 : 日志表 user_logs
create table user_logs(
  id int(11) not null auto_increment,
  operation varchar(20) not null comment '操作类型, insert/update/delete',
  operate_time datetime not null comment '操作时间',
  operate_id int(11) not null comment '操作的ID',
  operate_params varchar(500) comment '操作参数',
  primary key(`id`)
)engine=innodb default charset=utf8;

在这里插入图片描述

4.2 触发器-案例1(insert类型)

介绍
触发器是与表有关的数据库对象,指在insert/update/delete 之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作。
使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。
在这里插入图片描述

触发器类型NEW和OLD
INSERT型触发器NEW表示将要或者已经新增的数据
UPDATE型触发器OLD表示修改之前的数据, NEW表示将要或已经修改后的数据
DELETE型触发器OLD表示将要或者已经删除的数据

在这里插入图片描述
删除可以指定数据库!!!

create table user_logs(
  id int(11) not null auto_increment,
  operation varchar(20) not null comment '操作类型, insert/update/delete',
  operate_time datetime not null comment '操作时间',
  operate_id int(11) not null comment '操作的ID',
  operate_params varchar(500) comment '操作参数',
  primary key(`id`)
)engine=innodb default charset=utf8;



insert into tb_user(id, name, phone, email, profession, age, gender, status, createtime)
VALUES (25,'二皇子','18809091212','erhuangzi@163.com','软件工程',23,'1','1',now());

update tb_user set age = 32 where id = 23;

delete from tb_user where id = 25;
-- 插入数据触发器
create trigger tb_user_insert_trigger
    after insert on tb_user for each row
begin
    insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    (null, 'insert', now(), new.id, concat('插入的数据内容为: id=',new.id,',name=',new.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
end;


-- 查看
show triggers ;

-- 删除
drop trigger tb_user_insert_trigger;

-- 插入数据到tb_user
insert into tb_user(id, name, phone, email, profession, age, gender, status, createtime) VALUES (26,'三皇子','18809091212','erhuangzi@163.com','软件工程',23,'1','1',now());

这是查看的结果:
在这里插入图片描述
插入后的结果:
在这里插入图片描述

在这里插入图片描述

4.3 触发器-案例2(update类型)

-- 修改数据触发器
create trigger tb_user_update_trigger
    after update on tb_user for each row
begin
    insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    (null, 'update', now(), new.id,
        concat('更新之前的数据: id=',old.id,',name=',old.name, ', phone=', old.phone, ', email=', old.email, ', profession=', old.profession,
            ' | 更新之后的数据: id=',new.id,',name=',new.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
end;

show triggers ;

update tb_user set profession = '会计' where id = 23;

update tb_user set profession = '会计' where id <= 5;

在这里插入图片描述

4.4 触发器-案例3(delete类型)

-- 删除数据触发器
create trigger tb_user_delete_trigger
    after delete on tb_user for each row
begin
    insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    (null, 'delete', now(), old.id,
        concat('删除之前的数据: id=',old.id,',name=',old.name, ', phone=', old.phone, ', email=', old.email, ', profession=', old.profession));
end;

show triggers ;


delete from tb_user where id = 26;

在这里插入图片描述

4.5 视图&存储过程&触发器-小结

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1060573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL Server不允许保存更改的解决方法

SQL Server不允许保存更改的解决方法

深信服SG上网优化管理系统存在任意文件读取漏洞 附POC

文章目录 深信服SG上网优化管理系统存在任意文件读取漏洞 附POC1. 深信服SG上网优化管理系统简介2.漏洞描述3.影响版本4.fofa查询语句5.漏洞复现6.POC&EXP7.整改意见8.往期回顾 深信服SG上网优化管理系统存在任意文件读取漏洞 附POC 免责声明&#xff1a;请勿利用文章内的…

软件设计师_计算机网络_学习笔记

文章目录 4.1 网路技术标准与协议4.1.1 协议4.1.2 DHCP4.1.3 DNS的两种查询方式 4.2 计算机网络的分类4.2.1 拓扑结构 4.3 网络规划与设计4.3.1 遵循的原则4.3.2 逻辑网络设计4.3.3 物理网络设计4.3.4 分层设计 4.4 IP地址与子网划分4.4.1 子网划分4.4.2 特殊IP 4.5 HTML4.6 无…

C++入门-day01

一、认识C C融合了三种不同的编程方式 C代表的过程性语言在C基础上添加的类、结构体puls代表的面向对象语言C模板支持泛型编程 C完全兼容C的特性 Tips&#xff1a;侯捷老师提倡的Modren C是指C11、C14、C17和C20这些新标准所引入的一系列新特性和改进。在我们练习的时候也应当去…

QT实现TCP服务器客户端的实现

ser&#xff1a; widget.cpp&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);// 此时&#xf…

MyBatisPlus(八)范围查询

说明 范围查询&#xff0c;包括&#xff1a; 大于大于等于小于小于等于在范围内在范围外 大于&#xff1a;gt 代码 Testvoid gt() {LambdaQueryWrapper<User> wrapper new LambdaQueryWrapper<>();wrapper.gt(User::getAge, 20);List<User> users mapp…

Netty 4.1.98.Final 发布

Netty 4.1.98 稳定版已发布。Netty 是一个异步事件驱动的网络应用框架&#xff0c;主要用于可维护的高性能协议服务器和客户端的快速开发。 此版本还原了上一版本中所做的更改&#xff0c;这些更改导致 HTTP header 验证比所需的更严格 (#13615)。除此之外&#xff0c;当使用 n…

隐私交易成新刚需,Unijoin 凭什么优势杀出重围?

随着区块链技术的普及和发展&#xff0c;全球加密货币用户在持续增长&#xff0c;根据火币研究院公布的数据&#xff0c;2022年全球加密用户已达到 3.2亿人&#xff0c;目前全球人口总数超过了 80亿&#xff0c;加密货币用户渗透率已达到了 4%。 尤其是在 2020 年开启的 DeFi 牛…

mysql面试题12:讲一讲MySQL中什么是半同步复制?底层实现?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:讲一讲mysql中什么是半同步复制?底层实现? MySQL中的半同步复制(Semi-Synchronous Replication)是一种复制模式,它在主服务器将数据写入到二…

数组(数据结构)

优质博文&#xff1a;IT-BLOG-CN 一、简介 数组Array是一种线性表数据结构&#xff0c;它用一组连续的内存空间&#xff0c;存储一组具有相同类型的数据。 数组因具有连续的内存空间的特点&#xff0c;数据拥有非常高效率的“随机访问”&#xff0c;时间复杂度为O(1)。但因要保…

三分钟学习一个python小知识8-----------我的对python中pandas的理解--补充,

文章目录 一、利用pandas读入excel表&#xff0c;包括csv,xlsx等格式二、利用pandas读取没有表头的表格1.引入库 三、利用pandas读取有表头的表格四、利用pandas读取表格中的第一列五、利用pandas导出为excel数据总结 一、利用pandas读入excel表&#xff0c;包括csv,xlsx等格式…

实战型开发--3/3,clean code

编程的纯粹 hmmm&#xff0c;一开始在这个环节想聊一些具体的点&#xff0c;其实也就是《clean code》这本书中的点&#xff0c;但这个就还是更流于表面&#xff1b; 因为编码的过程&#xff0c;就更接近于运动员打球&#xff0c;艺术家绘画&#xff0c;棋手下棋的过程&#x…

四、互联网技术——局域网拓扑结构

文章目录 一、局域网拓扑结构二、虚拟局域网VLAN三、交换机VLAN划分四、VLAN的作用五、交换机的端口类型六、经典三层网络架构七、例题:局域网带宽利用分析八、网络安全基础九、恶意软件十、防火墙与入侵检测技术 一、局域网拓扑结构 局域网的主要特征由网络的拓扑结构、所采用…

windows系统下pycharm配置anaconda

参考&#xff1a;超详细的PycharmAnconda安装配置教程_pycharm conda_罅隙的博客-CSDN博客 下载好anaconda安装后&#xff0c;比如我们安装在D盘anaconda文件夹下&#xff0c;在pycharm配置好环境激活时出现问题&#xff0c;可能是电脑没有配置环境变量 需要将一下4行添加到电…

开发调试管理系统遇到的问题大全错误解决大全收集

问题大全错误解决大全 多模块项目依赖中&#xff0c;项目启动失败-org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException报错&#xff1a;Error: The project seems to require yarn but it‘s not installednpm ERR! fatal: Could not read fro…

速看:免费领取4台阿里云服务器_申请入口及领取流程

注册阿里云账号&#xff0c;免费领云服务器&#xff0c;最高领取4台云服务器&#xff0c;每月750小时&#xff0c;3个月免费试用时长&#xff0c;可快速搭建网站/小程序&#xff0c;部署开发环境&#xff0c;开发多种企业应用。阿里云服务器网分享阿里云服务器免费领取入口、免…

芯驰D9评测(1)--开箱硬件版

工业级的板卡和其他一般的“玩具”开发板还是要有所差别的&#xff0c;所以第一篇评测我们来仔细看看用料&#xff1a; 1. 全景图 用料足&#xff0c;做工扎实&#xff0c;接口都做了外围引出&#xff0c;底板配个铝合金外壳&#xff0c;就是妥妥的工业嵌入式主机。 2. 电源…

python 学习随笔 4

列表list 将序列前几个进行替换&#xff08;数量可以不同&#xff09; 将序列进行间隔替换&#xff08;必须保证数量相同&#xff0c;否则报错&#xff09; 删除序列内元素 向序列后新增一个元素 向序列后新增多个元素 将序列进行数乘&#xff08;不是产生几个序列哦&#xff0…

好奇喵 | Surface Web ---> Deep Web ---> Dark Web

前言 我们可能听说过深网(deep Web)、暗网(dark Web)等名词&#xff0c;有些时候可能会认为它们是一个东西&#xff0c;其实不然&#xff0c;两者的区别还是比较大的。 什么是deep web&#xff1f; 深网是网络的一部分&#xff0c;与之相对应的是表层网络&#xff08;surface …

【软考】4.2 关系代数/函数依赖/范式

《 关系代数 》 表和表之间的逻辑运算 笛卡尔积&#xff1a;S1 x S2 投影&#xff1a;π&#xff1b;选择某一列&#xff08;属性&#xff09;&#xff1b;一个关系R的投影操作结果也是一个关系&#xff0c;记作Πa&#xff0c;它由从关系R中选出的A列元素构成&#xff1b;选择…