mysql之视图、触发器、事务等

视图view(了解)

# 什么是视图
将SQL语句的查询结果当做虚拟表实体化保存起来,可以多次使用
   
   建议不要建立太多的视图表(命令行中不容易区分),视图表中的数据来自于原表,无法对视图表中的数据进行修改

create view 表名 as sql语句
create view teacher2course as
select * from teacher inner join course on teacher.tid = course.teacher_id;

# 删除视图表
drop view teacher2course;
   
# 视图使用频率不高

触发器trigger

# 触发器:满足特定条件后自动触发
关键字:trigger

在MySQL只有三种情况下可以触发

# before/after insert/update/delete

1.针对表的增
  增前 增后
   2.针对表的改
  改前 改后
   3.针对表的删
  删前 删后
       
# 语法结构
create trigger 触发器名称 before/after insert/update/delete on 表名 for each row
   begin
  sql语句
    end
   
# 触发器名字在命名是建议使用一下方式(见名知意)
tri_after_insert_t1、tri_before_delete_t1
   
# 如何修改SQL语句的结束符(结束符与分割符冲突)
delimiter $$

# 在MySQL中NEW特指数据对象可以通过点的方式获取字段对应的数据
id    name pwd  hobby
1     jason  123  read
NEW.name  >>>  jason
   

# 案例

CREATE TABLE cmd (
   id INT PRIMARY KEY auto_increment,
   USER CHAR (32),
   priv CHAR (10),
   cmd CHAR (64),
   sub_time datetime, #提交时间
   success enum ('yes', 'no') #0代表执行失败
);

CREATE TABLE errlog (
   id INT PRIMARY KEY auto_increment,
   err_cmd CHAR (64),
   err_time datetime
);

delimiter $$  # 将mysql默认的结束符由;换成$$
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
   if NEW.success = 'no' then  # 新记录都会被MySQL封装成NEW对象
       insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
   end if;
end $$
delimiter ;  # 结束之后记得再改回来,不然后面结束符就都是$$了

#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
   USER,
   priv,
   cmd,
   sub_time,
   success
)
VALUES
  ('tony','0755','ls -l /etc',NOW(),'yes'),
  ('tony','0755','cat /etc/passwd',NOW(),'no'),
  ('tony','0755','useradd xxx',NOW(),'no'),
  ('tony','0755','ps aux',NOW(),'yes');

# 查询errlog表记录
select * from errlog;
# 查看触发器
show triggers;(数据无法完全显示可以在后面加个\G)
# 删除触发器
drop trigger tri_after_insert_cmd;

事务

# 1、事务是什么      

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

# 2、事务的四大特性 (ACID)

     数据库事务 transanction 正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)

     (1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
       
     (2)一致性,事务的一致性保证数据处于一致状态。如果事务开始时系统处于一致状态,则事务结束时系统也应处于一致状态,不管事务成功还是失败。
  # 事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的
   
     (3)隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。 # 简而言之:事务与事务之间彼此互不干扰
       
     (4)持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

# 如何开启事务
start transaction;
# 如何回滚
rollback;
# 如何确认(确认之后表示事务完成,此时无法回滚)
commit;

存储过程

# 类似于python中的自定义函数

# 1.无参存储过程
delimiter $$
create procedure p1()
begin
select * from user;
end $$
delimiter ;
# 调用
call p1()

# 2.有参存储过程
delimiter $$
create procedure p2(
   in m int,  # in表示这个参数必须只能是传入不能被返回出去
   in n int,  
   out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
   select * from userinfo where id > m and id < n;
   set res=0;  # 用来标志存储过程是否执行
end $$
delimiter ;

# 代码操作存储过程
import pymysql
conn = pymysql.connect(
   host='127.0.0.1',
   port=3306,
   user='root',
   passwd='123',
   db='db6',
   charset='utf8',
   autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.callproc('p2',(1,3,10))
# @_p1_0=1,@_p1_1=3,@_p1_2=10;
print(cursor.fetchall())

# 查看存储过程
show  create procedure p2;
# 删除存储过程
drop procedure p2;

函数

# 相当于python中内置函数
"ps:可以通过help 函数名   查看帮助信息!"
# 1.移除指定字符
Trim、LTrim、RTrim

Examples:
   mysql> SELECT TRIM(' bar   ');
           -> 'bar'
   mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
           -> 'barxxx'
   mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
           -> 'bar'
   mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
           -> 'barx'

# 2.大小写转换
Lower、Upper

mysql> SELECT LOWER('QUADRATICALLY');
       -> 'quadratically

# 3.获取左右起始指定个数字符
Left、Right

mysql> SELECT LEFT('foobarbar', 5);
       -> 'fooba'

# 4.返回读音相似值(只对英文效果)
Soundex
"""
eg:客户表中有一个顾客登记的用户名为J.Lee
但如果这是输入错误真名其实叫J.Lie,可以使用soundex匹配发音类似的
where Soundex(name)=Soundex('J.Lie')
"""

# 5.日期格式:date_format
'''在MySQL中表示时间格式尽量采用2022-11-11形式'''
CREATE TABLE blog (
   id INT PRIMARY KEY auto_increment,
   NAME CHAR (32),
   sub_time datetime
);
INSERT INTO blog (NAME, sub_time)
VALUES
  ('第1篇','2015-03-01 11:31:21'),
  ('第2篇','2015-03-11 16:31:21'),
  ('第3篇','2016-07-01 10:21:31'),
  ('第4篇','2016-07-22 09:23:21'),
  ('第5篇','2016-07-23 10:11:11'),
  ('第6篇','2016-07-25 11:21:31'),
  ('第7篇','2017-03-01 15:33:21'),
  ('第8篇','2017-03-01 17:32:21'),
  ('第9篇','2017-03-01 18:31:21');
   
# 要求按照年和月分组
select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');

1.where Date(sub_time) = '2015-03-01'
2.where Year(sub_time)=2016 AND Month(sub_time)=07;
# 更多日期处理相关函数
adddate 增加一个日期
addtime 增加一个时间
datediff计算两个日期差值
 ...

流程控制

# if判断
if i = 1 THEN
      SELECT 1;
ELSEIF i = 2 THEN
      SELECT 2;
ELSE
      SELECT 7;
END IF;

# while循环
SET num = 0 ;
WHILE num < 10 DO
   SELECT
       num ;
   SET num = num + 1 ;
END WHILE ;

索引语慢查询优化

索引:简单的理解为可以帮助你加快数据查询速度的工具
   也可以把索引比喻成书的目录
 
算法:解决事物的办法
   入门级算法:二分法
  二分法前提:数据集必须有序

数据结构
二叉树(只能分两个叉)
b树 b+树(叶子节点添加了指针) b*树(枝节点也添加了指针)
   # 添加指针是为了加快范围查询的速度

将某个字段添加成索引就相当于依据该字段建立了一颗b+树从而加快查询速度
如果某个字段没有添加索引 那么依据该字段查询数据会非常的慢(一行行查找)

索引的分类

1.primary key
主键索引除了有加速查询的效果之外 还具有一定的约束条件
2.unique key
唯一键索引 除了有加速查询的效果之外 还具有一定的约束条件
3.index key
普通索引 只有加速查询的效果 没有额外约束
4.foreign key
# 注意外键不是索引 它仅仅是用来创建表与表之间关系的

数据库设计三大范式

# 什么是范式
"""
当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。
"""
# 简单来说:    
   第一范式:具有原子性(不可拆分)
   第二范式:主键列与非主键列遵循完全函数依赖关系
   第三范式:非主键列之间没有传递函数依赖关系(直接依赖关系)



补充(MYSQL查看存储过程函数)

查询数据库中的存储过程和函数

      select `name` from mysql.proc where db = 'xx' and `type` = 'PROCEDURE'   //存储过程
      select `name` from mysql.proc where db = 'xx' and `type` = 'FUNCTION'   //函数

      show procedure status; //存储过程
      show function status;     //函数

查看存储过程或函数的创建代码

  show create procedure proc_name;
  show create function func_name;

查看视图
  SELECT * from information_schema.VIEWS   //视图
  SELECT * from information_schema.TABLES   //

查看触发器
  SHOW TRIGGERS [FROM db_name] [LIKE expr]
  SELECT * FROM triggers T WHERE trigger_name=”mytrigger” \G

 

 

posted @ 2021-11-20 15:09  一叶松  阅读(152)  评论(0编辑  收藏  举报