1. 视图
# 创建表
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‘) # no代表执行失败 ); CREATE TABLE errlog ( id INT PRIMARY KEY auto_increment, err_cmd CHAR (64), err_time datetime );
# 创建触发器
补充:NEW对象指代的就是当前记录 delimiter $$ # 将mysql默认的结束符由;换成$$(因为你的sql语句中可能有多个 ; ,而原本的操作是只要遇到一个 ; 就结束了)
# 只对当前窗口有效 create trigger tri_after_insert_cmd after insert on cmd for each row begin if NEW.success = ‘no‘ then insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time); end if; end $$ delimiter ; # 结束之后记得再改回来,不然后面结束符就都是$$了
# 删除触发器
drop trigger tri_after_insert_cmd;
# 修改数据之前先开启事务操作 start transaction; # 修改操作 update user set balance=900 where name=‘wsb‘; #买支付100元 update user set balance=1010 where name=‘egon‘; #中介拿走10元 update user set balance=1090 where name=‘ysb‘; #卖家拿到90元 # 回滚到上一个状态 rollback; # 开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘
"""开启事务检测操作是否完整,不完整主动回滚到上一个状态,如果完整就应该执行commit操作""" try: update user set balance=900 where name=‘wsb‘; #买支付100元 update user set balance=1010 where name=‘egon‘; #中介拿走10元 update user set balance=1090 where name=‘ysb‘; #卖家拿到90元 except 异常: # 异常如何检测?????---> 下面的存储过程 rollback; else: commit;
# 语法 delimiter $$ create procedure 过程名( in m int, # in表示这个参数只能是传入,不能被返回 in n int, out res int # out表示这个参数可以被返回出去 inout res int # inout表示这个参数既可以传入,也可以被返回出去 一般不使用 ) # 关键字in/out/inout 值 类型 begin select 字段名 from 表名 where 条件; # 如:select tname from teacher where tid > m and tid < n; set res = 0 # 修改可以返回出去的值,再进行查看,就可以知道有没有存储成功 end $$ delimiter ;
如何使用??
# 大前提:存储过程是在哪个库下面创建的,就只能在对应的库下面使用! # 使用一:直接在mysql中调用 set @res = 10 # res的值是用来判断存储过程是否被执行成功的依据 # 所以需要先定义一个变量@res存储10 call p1(2,4,10) # 报错 call p1(2,4,@res) #使用 call + 过程名字(参数) 来调用存储过程 # 查看结果 select @res; # @res发生了变化,则表示存储过程执行成功 # 使用二:在python程序中调用 # pymysql连接mysql # 产生的游标 cursor.callproc(‘p1‘,(2,4,10))
# 内部的原理:@_p1_0 = 2 @_p1_1 = 4 @_p1_2 = 10; # 0、1、2对应的为括号内第二个参数索引位置 cursor.execute(‘select @_p1_2;‘) # 查看是否有变化
5. 函数
mysql 内置的函数只能在 sql 语句中使用!
参考博客:<http://www.cnblogs.com/linhaifeng/articles/7495918.html#_label2>
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‘);
6.流程控制
# if条件语句 delimiter // CREATE PROCEDURE proc_if () # 关键词 procedure BEGIN declare i int default 0; if i = 1 THEN SELECT 1; ELSEIF i = 2 THEN SELECT 2; ELSE SELECT 7; END IF; END // delimiter ;
# while循环 delimiter // CREATE PROCEDURE proc_while () BEGIN DECLARE num INT ; SET num = 0 ; WHILE num < 10 DO SELECT num ; SET num = num + 1 ; END WHILE ; END // delimiter ;
7. 索引与慢查询优化
#### b+树 <https://images2017.cnblogs.com/blog/1036857/201709/1036857-20170912011123500-158121126.png> 只有叶子结点存放真实数据,根和树枝节点存的仅仅是虚拟数据 查询次数由树的层级决定,层级越低次数越少 一个磁盘块儿的大小是一定的,那也就意味着能存的数据量是一定的。如何保证树的层级最低呢?一个磁盘块儿存放占用空间比较小的数据项 思考我们应该给我们一张表里面的什么字段字段建立索引能够降低树的层级高度>>> 主键id字段
#### **聚集索引(primary key)** 聚集索引其实指的就是表的主键,innodb引擎规定一张表中必须要有主键。先来回顾一下存储引擎。 myisam在建表的时候对应到硬盘有几个文件(三个)? innodb在建表的时候对应到硬盘有几个文件(两个)?frm文件只存放表结构,不可能放索引,也就意味着innodb的索引跟数据都放在idb表数据文件中。 **特点:**叶子结点放的一条条完整的记录
#### 辅助索引(unique,index) 辅助索引:查询数据的时候不可能都是用id作为筛选条件,也可能会用name,password等字段信息,那么这个时候就无法利用到聚集索引的加速查询效果。就需要给其他字段建立索引,这些索引就叫辅助索引 **特点:**叶子结点存放的是辅助索引字段对应的那条记录的主键的值(比如:按照name字段创建索引,那么叶子节点存放的是:{name对应的值:name所在的那条记录的主键值})
select name from user where name=‘jason‘;
上述语句叫覆盖索引:只在辅助索引的叶子节点中就已经找到了所有我们想要的数据
select age from user where name=‘jason‘; 上述语句叫非覆盖索引,虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找
原文:https://www.cnblogs.com/pupy/p/11402431.html