Python mysql中的:视图 触发器 事务 存储过程 mysql内置函数 流程控制 b+树 索引 慢日志查询 权限管理
语法: create view 视图名 as 查询语句; 例: create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id;
4.注意:
#1.视图只有表结构,视图中的数据还是来源于原来的表
#2.不要改动视图表中的数据
#3.一般情况下不会频繁的使用视图来写业务逻辑
create trigger 触发器的名字 after/before insert/update/delete on 表名 for each row begin sql语句 end # 删除触发器 drop trigger tri_after_insert_cmd; 细分: # 针对插入 create trigger tri_after_insert_t1 after insert on 表名 for each row begin sql代码。。。 end create trigger tri_after_insert_t2 before insert on 表名 for each row begin sql代码。。。 end # 针对删除 create trigger tri_after_delete_t1 after delete on 表名 for each row begin sql代码。。。 end create trigger tri_after_delete_t2 before delete on 表名 for each row begin sql代码。。。 end # 针对修改 create trigger tri_after_update_t1 after update on 表名 for each row begin sql代码。。。 end create trigger tri_after_update_t2 before update on 表名 for each row begin sql代码。。。 end 案例: 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 ; # 结束之后记得再改回来,不然后面结束符就都是$$了
#表准备 create table user( id int primary key auto_increment, name char(32), balance int ); insert into user(name,balance) values ('wsb',1000), ('egon',1000), ('ysb',1000); 1.# 修改数据之前先开启事务操作 start transaction; 2.# 一系列操作 例如 # 修改操作 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元 #3.# 回滚到上一个状态即没有第二步修改操作 rollback; 4.# 开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘,(提交后再执行回滚,没有任何回滚效果) commit; """开启事务检测操作是否完整,不完整主动回滚到上一个状态,如果完整就应该执行commit操作""" # 站在python代码的角度,应该实现的伪代码逻辑, 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;
1.# 创建过程 delimiter $$ create procedure p1( in m int, # in表示这个参数必须只能是传入不能被返回出去 in n int, out res int # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去 ) begin select tname from teacher where tid > m and tid < n; # sql语句 set res=0; # 返回值 end $$ delimiter ; 2.# 如何使用 # 1、直接在mysql中调用 set @res=10 # res的值是用来判断存储过程是否被执行成功的依据,所以需要先定义一个变量@res存储10 call p1(2,4,10); # 报错 call p1(2,4,@res); # 查看结果 select @res; # 执行成功,@res变量值发生了变化 # 2、在python程序中调用 pymysql链接mysql 产生的游表cursor.callproc('p1',(2,4,10)) # 内部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10; cursor.excute('select @_p1_2;') # 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用!!!存储
3.案例:
# 3、存储过程与事务使用举例(了解) delimiter // create PROCEDURE p5( OUT p_return_code tinyint ) BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR set p_return_code = 1; rollback; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING set p_return_code = 2; rollback; END; START TRANSACTION; update user set balance=900 where id =1; update user123 set balance=1010 where id = 2; update user set balance=1090 where id =3; COMMIT; -- SUCCESS set p_return_code = 0; #0代表执行成功 END // delimiter ;
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');
流程控制
# 第一种: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '' # )engine=Innodb charset=utf8; # 第二种: alter table t1 change id id int auto_increment primary key;
唯一索引: # 第一种: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '', # unique ix_name (name) # )engine=Innodb charset=utf8; # # 第二种: # create unique index 索引名称(ix_name) on 表名(t1)(name); # create unique index 索引名称(ix_name_age) on 表名(t1)(name,age);
普通索引: # # 第一种: # create table t1( # id int auto_increment primary key, # name varchar(32) not null default '', # index ix_name (name) # )engine=Innodb charset=utf8; # # 第二种: # create index 索引名称(ix_name) on 表名(t1)(name);
drop index 索引名称(ix_name) on 表名(t1);
版本5.3以下: # 删除和修改的速度就变慢了 # # 版本5.5以上: # 删除和修改的速度不是特别的慢
1. show variables like '%query%'; # # 2. set global long_query_time = 1; 设置慢查询的时间 # 3. slow_query_log = ON # 4. slow_query_log_file = E:\program\mysql-5.6.44-winx64\data\oldboy-slow.log
show variables like '%general%'; # +------------------+------------------------------------------------+ # | Variable_name | Value | # +------------------+------------------------------------------------+ # | general_log | ON | # | general_log_file | E:\program\mysql-5.6.44-winx64\data\oldboy.log | # +------------------+------------------------------------------------+ # set global general_log = ON;
创建用户 # create user '用户名'@'IP地址' identified by '密码'; # creaee user 'zekai'@'192.168.1.123' identified by '123qwe'; # creaee user 'zekai'@'192.168.1.%' identified by '123qwe'; # create user 'zekai'@'%' identified by '123qwe'; # # 删除用户 # drop user '用户名'@'IP地址'; # 修改用户 # rename user '用户名'@'IP地址' to '新用户名'@'IP地址'; # # 修改密码 # set password for '用户名'@'IP地址' = Password('新密码') # # 授权: # grant 权限 on 数据库.表 to '用户'@'IP地址' -- 授权 # # grant select on db1.* to 'zekai'@'%'; # grant select on *.* to 'zekai'@'%'; # grant select, insert, delete on db1.* to 'zekai'@'%'; # # 记住: # flush privileges;
#1.注意:
只有叶子结点存放真实数据,根和树枝节点存的仅仅是虚拟数据
查询次数由树的层级决定,层级越低次数越少一个磁盘块儿的大小是一定的,那也就意味着能存的数据量是一定的。如何保证树的层级最低呢?一个磁盘块儿存放占用空间比较小的数据项,思考我们应该给我们一张表里面的什么字段字段建立索引能够降低树的层级高度>>> 主键id字段。
#1.聚集索引其实指的就是表的主键,innodb引擎规定一张表中必须要有主键。
#2.辅助索引分类:
select name from user where name='jason';
上述语句叫覆盖索引:只在辅助索引的叶子节点中就已经找到了所有我们想要的数据
select age from user where name='jason';
上述语句叫非覆盖索引,虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找