一:视图

  01:介绍

  1.   视图是一个虚拟表(非真实存在),是跑到内存中的表,真实表是硬盘上的表,怎么就得到了虚拟表,就是你查询的结果,只不过之
  2. 前我们查询出来的虚拟表,从内存中取出来显示在屏幕上,内存中就没有了这些表的数据,但是下次我要是想用这个虚拟表呢,没办法,
  3. 只能重新查一次,每次都要重新查。其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结
  4. 果集,可以将该结果集当做表来使用。如果我们想查询一些有关联的表,比如我们前面的老师学生班级什么的表,我可能需要几个表联合
  5. 查询的结果,但是这几张表在硬盘上是单独存的,所以我们需要通过查询的手段,将这些表在内存中拼成一个虚拟表,然后是不是我们再
  6. 基于虚拟表在进行进一步的查询,然后我们如果以后想重新再查一下这些关系数据,还需要对硬盘上这些表进行再次的重新加载到内容,
  7. 联合成虚拟表,然后再筛选等等的操作,意味着咱们每次都在写重复的sql语句,那有没有好的方法啊,其实很简单,我们把重复用的这些
  8. sql逻辑封装起来,然后下次使用的时候直接调用这个封装好的操作就可以了,这个封装起来的操作就类似我们下面要说的视图为什么要用
  9. 视图:使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂
  10. sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中
  11. 的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用

二:触发器:(注意:触发器不能进行 查操作 )

  1. 触发器不是由用户去触发的,而是程序事先设定好的,由程序自动触发的。触发器里面可以进行 增/删/改(触发器无法由用户直接调用,而由对表的【增/删/改】操作被动引发的。)

  01:创建触发器:

    001:插入数据前触发触发器
  1. create trigger tri_before_insert_1 before insert on 1 for each row
  2. begin
  3. ......#beginend 里面写触发器要做的事情,而且要注意代码缩进,给触发器起名字的时候,
  4. 最好像tri_befores_insert_1 有表示意义,看名字就知道是给哪个表设置的触发器。
  5. end
    002:插入数据后触发触发器
  1. create trigger tri_after_insert_1 after insert on 1 for each row
  2. begin
  3. ...#需要触发器做的事情
  4. end
    003:删除数据前触发触发器
  1. create trigger tri_before_delete_1 before delete on 1 for each row
  2. begin
  3. ......#需要触发器做的事情
  4. end
    004:更新数据前触发触发器
  1. create trigger tri_before_update_1 after update on 1 for each row
  2. begin
  3. ...触发器需要做的事情
  4.  
  5. end
    005:更新数据后触发触发器
  1. create trigger tri_after_update_1 after update on 1 for each row
  2. begin
  3. .... 触发器需要做的事情
  4. end

  02:使用案例: #准备表

  1. CREATE TABLE cmd ( #这是一张指令信息表,你在系统里面执行的任何的系统命令都在表里面写一条记录
  2. id INT PRIMARY KEY auto_increment, #id
  3. USER CHAR (32), #用户
  4. priv CHAR (10), #权限
  5. cmd CHAR (64), #指令
  6. sub_time datetime, #提交时间
  7. success enum ('yes', 'no') #是否执行成功,0代表执行失败
  8. );
  9.  
  10. CREATE TABLE errlog ( #指令执行错误的信息统计表,专门提取上面cmd表的错误记录
  11. id INT PRIMARY KEY auto_increment, #id
  12. err_cmd CHAR (64), #错误指令
  13. err_time datetime #错误命令的提交时间
  14. );
  1. #现在的需求是:不管正确或者错误的cmd,都需要往cmd表里面插入,然后,如果是错误的记录,还需要往errlog表里面插入一条记录
  2. #若果没有触发器,我们会怎么实现,我们完全可以通过咱们的应用程序来做,根据cmd表里面的success这个字段是哪个值(yes成功,no表示失败),
  3. 在给cmd插入记录的时候,判断一下这个值是yes或者no,来判断一下成功或者失败,如果失败了,直接给errlog来插入一条记录
  4. #但是mysql说,你的应用程序可以省事儿了,你只需要往cmd表里面插入数据就行了,没必要你自己来判断了,可以使用触发器来实现,可以判断你插
  5. 入的这条记录的success这个字段对应的值,然后自动来触发触发器,进行errlog表的数据插入
  1. #创建触发器
  2. delimiter // (或者写$$,其他符号也行,但是不要写mysql不能认识的,知道一下就行了),delimiter 是告诉mysql,遇到这句话的时候,
    就将sql语句的结束符分号改成delimiter后面的//
  3. CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW #在你cmd表插入一条记录之后触发的。
  4. BEGIN #每次给cmd插入一条记录的时候,都会被mysql封装成一个对象,叫做NEW,里面的字段都是这个NEW的属性
  5. IF NEW.success = 'no' THEN #mysql里面是可以写这种判断的,等值判断只有一个等号,然后写then
  6. INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号,并且注意,我们必须用delimiter来包裹,
    不然,mysql一看到分号,就认为你的sql结束了,
  7.  
  8. 所以会报错
  9. END IF ; #然后写end if,必须加分号
  10. END// #只有遇到//这个完成的sql才算结束
  11. delimiter ; #然后将mysql的结束符改回为分号

#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志

  1. mysql> insert into cmd(
  2. -> user,
  3. -> priv,
  4. -> cmd,
  5. -> sub_time,
  6. -> success
  7. -> )
  8. -> values
  9. -> ("","","ls-1 /etc",now(),"yes"),
  10. -> ("","","cat /etc/passwd",now(),"no"),
  11. -> ("","","useradd xxx",now(),"no"),
  12. -> ("","","ps aux",now(),"yes");
  13. Query OK, 4 rows affected (0.16 sec)
  14. Records: 4 Duplicates: 0 Warnings: 0

查询错误日志,发现有两条

  1. mysql> select * from errlog;
  2. +----+-----------------+---------------------+
  3. | id | err_cmd | err_time |
  4. +----+-----------------+---------------------+
  5. | 1 | cat /etc/passwd | 2018-12-11 16:54:42 |
  6. | 2 | useradd xxx | 2018-12-11 16:54:42 |
  7. +----+-----------------+---------------------+
  8. 2 rows in set (0.00 sec)

  03:删除触发器:

  1. drop trigger tri_after_insert_cmd(触发器名字)

三:事件

  1. 事物的四大特性:(原子性,一致性,持久性,隔离性)

  01:原子性(Atomicity):事务开始执行,要么成功的话一起成功,要么失败的话全部都失败。只要有一个失败则全部都失败。

  (正确版的原子性)事务的原子性例子:
  1. mysql> create table user(
  2. -> id int primary key auto_increment,
  3. -> name char(32),
  4. -> balance int
  5. -> );
  6. Query OK, 0 rows affected (0.19 sec)
  7.  
  8. mysql> insert into user(name,balance)
  9. -> values
  10. -> ("wsb",1000),
  11. -> ("chao",1000),
  12. -> ("ysb",1000);
  13. Query OK, 3 rows affected (0.04 sec)
  14. Records: 3 Duplicates: 0 Warnings: 0
  15.  
  16. #原子操作
  17. mysql> start transaction; #开启事务
  18. Query OK, 0 rows affected (0.00 sec)
  19.  
  20. mysql> update user set balance=910 where name="wsb";
  21. Query OK, 1 row affected (0.03 sec)
  22. Rows matched: 1 Changed: 1 Warnings: 0
  23.  
  24. mysql> update user set balance=1090 where name="ysb";
  25. Query OK, 1 row affected (0.00 sec)
  26. Rows matched: 1 Changed: 1 Warnings: 0
  27.  
  28. #这些操作都只是在内存中操作,还未写入文件,先看下他们的数据;
  29. mysql> select * from user;
  30. +----+------+---------+
  31. | id | name | balance |
  32. +----+------+---------+
  33. | 1 | wsb | 900 |
  34. | 2 | chao | 1010 |
  35. | 3 | ysb | 1090 |
  36. +----+------+---------+
  37. 3 rows in set (0.00 sec)
  38.  
  39. 然后退出(quit 再进入查看,user表的信息还是未被改变,说明还未被写入磁盘中()还未用commit
  40. mysql> select * from user;
  41. +----+------+---------+
  42. | id | name | balance |
  43. +----+------+---------+
  44. | 1 | wsb | 1000 |
  45. | 2 | chao | 1000 |
  46. | 3 | ysb | 1000 |
  47. +----+------+---------+
  48. 3 rows in set (0.00 sec)
  49.  
  50. 02:commit 写入磁盘
  51. 过程:
  52. create table user(
  53. id int primary key auto_increment,
  54. name char(32),
  55. balance int
  56. );
  57.  
  58. insert into user(name,balance)
  59. values
  60. ('wsb',1000),
  61. ('chao',1000),
  62. ('ysb',1000);
  63.  
  64. #原子操作
  65. start transaction;
  66. update user set balance=900 where name='wsb'; #买支付100元
  67. update user set balance=1010 where name='chao'; #中介拿走10元
  68. update user set balance=1090 where name='ysb'; #卖家拿到90元
  69. commit; #只要不进行commit操作,就没有保存下来,没有刷到硬盘上
  70. 现在用commit命令执行写入磁盘中。(现在需要把前面的表重新创建,所以还是先drop再新建表吧)
  71. 显示commit后的结果:这个是从磁盘读取的数据,说明已经将数据写入磁盘中了。
  72. mysql> select * from user;
  73. +----+------+---------+
  74. | id | name | balance |
  75. +----+------+---------+
  76. | 1 | wsb | 900 |
  77. | 2 | chao | 1010 |
  78. | 3 | ysb | 1090 |
  79. +----+------+---------+
  80. 3 rows in set (0.00 sec)
  81.  
  82. 错误版的需要回滚的的原子性(例子说明):
  83. create table user(
  84. id int primary key auto_increment,
  85. name char(32),
  86. balance int
  87. );
  88.  
  89. insert into user(name,balance)
  90. values
  91. ('wsb',1000),
  92. ('chao',1000),
  93. ('ysb',1000);
  94.  
  95. #开启事务:
  96. mysql> start transaction; #开启事务
  97. Query OK, 0 rows affected (0.00 sec)
  98.  
  99. mysql> update user set balance=900 where name='wsb'; #买支付100元
  100. Query OK, 1 row affected (0.00 sec)
  101. Rows matched: 1 Changed: 1 Warnings: 0
  102.  
  103. mysql> update user set balance=1010 where name='chao'; #中介拿走10元
  104. Query OK, 1 row affected (0.00 sec)
  105. Rows matched: 1 Changed: 1 Warnings: 0
  106.  
  107. mysql> uppdate user11 set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到,并没有user11这个用户信息
  108. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL serve
  109. sb'' at line 1
  110. 查看事务出现异常后各用户的信息:(可以看到前面两项执行了的语句,数据还是改了并未出现回滚,因此我们需要自行设置回滚)
  111. mysql> select * from user;
  112. +----+------+---------+
  113. | id | name | balance |
  114. +----+------+---------+
  115. | 1 | wsb | 900 |
  116. | 2 | chao | 1010 |
  117. | 3 | ysb | 1000 |
  118. +----+------+---------+
  119. 3 rows in set (0.00 sec)
  120.  
  121. 上面的只要写了执行 commit; 操作,数据就写入到磁盘中了,再进行回滚rollback就不行了,就算quit出来再进去库里面进行查询,结果还是
  122. 修改后的数据,就算地三条语句没有执行,前面两条数据执行后已经被commit 写入磁盘中了。
  123. 就像这样:
  124. mysql> select * from user;
  125. +----+------+---------+
  126. | id | name | balance |
  127. +----+------+---------+
  128. | 1 | wsb | 900 | #数据正常被改了,因为执行了commit;
  129. | 2 | chao | 1010 | #数据正常被改了,因为执行了commit;
  130. | 3 | ysb | 1000 | #数据没有被改(报错语句),但是也被写入磁盘中了。
  131. +----+------+---------+
  132. 3 rows in set (0.00 sec)

  03:需要解决问题:(就是我需要判断我在修改数据的时候判断语句的正确性,如果全部语句正确则执行commit; 如果有其中一条不正确,则所有的
    执行语句都不执行成功,并将数据回滚到初始化。

    001:出现异常就立即回滚:
  1. start transaction;
  2. update user set balance=900 where name='wsb'; #买支付100元
  3. update user set balance=1010 where name='chao'; #中介拿走10元
  4. uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
  5. rollback; #如果上面三个sql语句出现了异常,就直接rollback,数据就直接回到原来的状态了。但是执行了commit之后,rollback这个操作就没法回滚了
  6. #我们要做的是检测这几个sql语句是否异常,没有异常直接commit,有异常就rollback,但是现在单纯的只是开启了事务,但是还没有说如何检测异常,我们先来一个存储过程来捕获异常,
  7. commit;
  002:通过存储过程来捕获异常回滚
  1.   #通过存储过程来捕获异常:(写存储过程的是,注意每一行都不要缩进!!!
  2. 02:一致性(Consistency):事务开始前和结束后,数据库的完整性没有被破坏掉.
  3. 03:持久性(Isolation):事务完成后,事务对数据库的所有更新将被保存在本地不能回滚。
  4. 04:隔离型(Durability):同一时间只能允许一个事务对请求数据,不同的事务之间不会彼此干扰

四:存储过程

  1:什么叫存储过程:存储过程包括了一系列的sql语句,存储过程放入mysql中,通过调用它的名字可以执行其内部的

  1. 一系列的sql。(存储过程其实就是一堆的sql的集合体)
  2. 优点:
  3. 01:用于替代程序写的sql语句,实现了程序与sql解耦
  4. 02:基于网络传输,传输别名的数据量小,而直接传sql语句的话数据量大
  5. 缺点:
  6. 01:扩展不方便

  2:程序与数据库结合使用的三种方式:

  1. 01mysql:存储过程
  2. 程序: 调用存储过程
  3.  
  4. 02mysql
  5. 程序:纯sql语句
  6.  
  7. 03mysql
  8. 程序类和对象,即orm(本质还是纯sql语句)

day--40 mysql-视图,触发器,存储过程,函数总结的更多相关文章

  1. mysql 视图 触发器 存储过程 函数事务 索引

    mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...

  2. Mysql 视图,触发器,存储过程,函数,事务

    视图 视图虚拟表,是一个我们真实查询结果表,我们希望将某次查询出来的结果作为单独的一个表,就叫视图,无法对图字段内容进行增删改. --格式: CREATE VIEW 视图名字 AS 操作; --比如: ...

  3. day40 mycql 视图,触发器,存储过程,函数

    视图,触发器,存储过程,自定义函数 -- 回顾 1.mysql 约束 1.非空 not null 2. 主键约束 primary key 3. 唯一约束 unique 4. 外键约束 foreign ...

  4. mysql视图 触发器 事物 函数 存储过程

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  5. Mysql学习---视图/触发器/存储过程/函数/执行计划/sql优化 180101

    视图 视图: 视图是一个虚拟表(非真实存在),动态获取数据,仅仅能做查询操作 本质:[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用.由 ...

  6. MySQL 索引 视图 触发器 存储过程 函数

    1.索引 索引相当于图书的目录,可以帮助用户快速的找到需要的内容. 数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万 ...

  7. MySQL 视图触发器事务存储过程函数

    事务  致命三问 什么是事务:开启了一个包含多条SQL语句的事务,这些SQL语句要么都执行成功,要么有别想成功:例如A向B转账,二人账户并不属于一家银行,在转账过程中由于网络问题,导致A显示转账 成功 ...

  8. MySQL 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化

    视图 1.什么是视图? 视图就是通过查询得到的一张虚拟表,然后保存下来,下次可直接使用 2.为什么要使用视图? 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图? create view ...

  9. MySQL——视图/触发器/事务/存储过程/函数/流程控制

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  10. 2020重新出发,MySql基础,MySql视图&索引&存储过程&触发器

    @ 目录 视图是什么 视图的优点 1) 定制用户数据,聚焦特定的数据 2) 简化数据操作 3) 提高数据的安全性 4) 共享所需数据 5) 更改数据格式 6) 重用 SQL 语句 MySQL创建视图 ...

随机推荐

  1. Pacemaker实现双机热备

    在互联网高速发展的今天,尤其在电子商务的发展,要求服务器能够提供不间断服务.在电子商务中,如果服务器宕机,造成的损失是不可估量的.要保证服务器不间断服务,就需要对服务器实现冗余.在众多的实现服务器冗余 ...

  2. [转]SQLServer添加UPDATE回滚日志(update/delete/insert)

    下面直接上代码(copy到你的数据库里面直接就可以运行): CREATE PROCEDURE [dbo].[SP_UPDATE_LOG] ) AS BEGIN SET NOCOUNT ON; IF N ...

  3. 分布式全文检索系统SolrCloud简介

    前言 本文简单描述SolrCloud的特性,基本结构和入门,基于Solr4.5版本. Lucene是一个Java语言编写的利用倒排原理实现的文本检索类库.Solr是以Lucene为基础实现的文本检索应 ...

  4. 170318 11:44:26 [ERROR] Can't start server: can't create PID file: No space left on device

    数据库挂了.打开远程,进了系统,service mysqld stop 失败.service mysqld start等了好大一会,提示Timeout error occurred trying to ...

  5. 661. Image Smoother色阶中和器

    [抄题]: Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoo ...

  6. opennebule 创建cdrom数据发送

    {","csrftoken":"b9b5026f1a92180b789971ed8e21d28b"}

  7. vs2017不是完全支持c99

    1.比如c99里面有一个特性, int count[]={0,[5]=7,9,10} 这种在VS2017里面是编译不通过的.; 2.c99有一个变长数组的概念(VLA),但是vs2017不支持.

  8. Apache apxs命令

    一.简介 apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载 ...

  9. integer encoding vs 1-hot (py)

    https://github.com/szilard/benchm-ml/issues/1 glouppe commented on 7 May 2015 Thanks for the benchma ...

  10. Luogu 4091 [HEOI2016/TJOI2016]求和

    BZOJ 4555 一道模板题. 第二类斯特林数有公式: $$S(n, m) = \frac{1}{m!}\sum_{i = 0}^{m}(-1)^i\binom{m}{i}(m - i)^n$$ 考 ...