shiwu

----------------------------------------------视图---------------------------------------------

视图是什么

#视图是有一条sql语句的查询结果构成的虚拟表
#其不是物理存在的  使用方式与普通表相同

 视图的作用

#1.简化sql语句的编写

#2.限制可以查看的数据
可以使用权限来完成  权限某一个库 的某一个表 的某一个字段
例如:一张表存储了所有人的工资 但是每个员工只能看自己的工资信息  那就可以用视图来限制

创建视图

#语法:CREATE VIEW 视图名称 AS  SQL语句
#语法:CREATE or repalce] VIEW 视图名称 [(column_list)]  AS  SQL语句
加上or repiale 时如果已经视图存在相同视图则替换原有视图

column_list指定哪些字段要出现在视图中

 视图的增删改查(视图的增删改查会同步到原始表)

视图是一张虚拟表 所以使用方式与普通表没有任何区别

#**查看视图**

1.desc view_name;   //查看数据结构 索引信息不会体现在视图中

2.show create view view_name;//查看 创建语句

#**修改视图**

alter view view_name  as select_statement

#**删除视图**

drop view view_name

 案例之简化sql语句

create database db02 charset utf8;
use db02
create table student(
  s_id int(3),
  name varchar(20),
  math float,
  chinese float 
);
insert into student values(1,'tom',80,70),(2,'jack',80,80),(3,'rose',60,75);

create table stu_info(
  s_id int(3),
  class varchar(50),
  addr varchar(100)
);
insert into stu_info values(1,'二班','安徽'),(2,'二班','湖南'),(3,'三班','黑龙江');
准备数据
#不使用视图,每次查询信息,都需要连接查询
select student.s_id,student.name ,stu_info.class
from student,stu_info 
where student.s_id=stu_info.s_id;


#创建视图
create view view_student as select student.s_id,student.name ,stu_info.class from student,stu_info where student.s_id=stu_info.s_id;

#以后再查询,只需要select *from view_student,不需要再每次连接查询,简化代码

案例二、隔离数据(设置权限)

# 创建工资表
create table salarys(
id int primary key,
name char(10),
salary double,
dept char(10)
);
insert into salarys values
(1,"刘强东",900000,"市场"),
(2,"马云",800090,"市场"),
(3,"李彦宏",989090,"财务"),
(4,"马化腾",87879999,"财务");
准备数据
#设置一个部门都可观看
mysql> create view dept_view as select *from salarys where dept = "财务";
Query OK, 0 rows affected (0.13 sec)

mysql> select *from dept_view;
+----+-----------+----------+--------+
| id | name      | salary   | dept   |
+----+-----------+----------+--------+
|  3 | 李彦宏    |   989090 | 财务   |
|  4 | 马化腾    | 87879999 | 财务   |
+----+-----------+----------+--------+
2 rows in set (0.00 sec)


#设置仅可自己看自己的薪资
mysql> create view self_view as select *from salarys where name = "李彦宏";
Query OK, 0 rows affected (1.85 sec)

mysql> select *from self_view;
+----+-----------+--------+--------+
| id | name      | salary | dept   |
+----+-----------+--------+--------+
|  3 | 李彦宏    | 989090 | 财务   |
+----+-----------+--------+--------+
1 row in set (0.01 sec)

 --------------------------------------------------------触发器---------------------------------------------------------------------------

### 什么是触发器

触发器是一段与某个表相关的mysql程序
当这个表在某个时间点发生了某种事件时 将会自动执行相应的触发器程序

### 何时使用触发器

当我们想要在一个表记录被更新时做一些操作时就可以使用触发器

但是我们完全可以在python中来完成这个事情,因为python的扩展性更强,语法更简单



### 创建触发器

```mysql
语法:
CREATE TRIGGER t_name t_time t_event ON table_name FOR EACH ROW
begin
stmts.....
end
```

支持的时间点(t_time):时间发生前和发生前后 before|after

支持的事件(t_event): update insert delete

在触发器中可以访问到将被修改的那一行数据
根据事件不同 能访问也不同
update 可用OLD访问旧数据 NEW访问新数据
insert 可用NEW访问新数据
delete 可用OLD访问旧数据

可以将NEW和OLD看做一个对象其中封装了这条数据的所有字段

案例:

有cmd表和错误日志表,需求:在cmd执行失败时自动将信息存储到错误日志表中

```mysql
#准备数据
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 //
create trigger trigger1 after insert on cmd for each row
begin
if new.success = "no" then
    insert into errlog values(null,new.cmd,new.sub_time);
end if;
end//
delimiter ;

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

```

`delimiter` 用于修改默认的行结束符 ,由于在触发器中有多条sql语句他们需要使用分号来结束,但是触发器是一个整体,所以我们需要先更换默认的结束符,在触发器编写完后在将结束符设置回分号

注意:

1.外键不能触发事件 主表删除了某个主键  从表也会相应删除 但是并不会执行触发器
2.触发器中不能使用事务,不能使用select 查询数据
3.相同时间点的相同事件的触发器 不能同时存在

### 删除触发器

```mysql
语法:
drop trigger trigger_name;
案例:
drop trigger trigger1;
```

同样的这种需求我们完全可以在python中来完成! mysql最想完成的事情是将所有能处理的逻辑全部放到mysql中,那样一来应用程序开发者的活儿就变少了,相应的数据库管理员的工资就高了,可惜大多中小公司都没有专门的DBA;

**疑惑:**修改行结束符后,触发器内的sql语句任然是以分号结束,为什么? 实际上在mysql中输入分号回车,mysql会立即将语句发送给服务器端,修改行结束符仅仅是告诉mysql客户端,语句没有写完,不要立即发送!

练习: 编写触发器用于将更新记录插入另一个表

```mysql
create table blog(id int primary key auto_increment,content text,b_id int,foreign key(b_id) references blog(id),update_time timestamp);

create table blogs(id int primary key auto_increment,content text,b_id int,foreign key(b_id) references blog(id),update_time timestamp);

delimiter //
create trigger t10 before update on blog for each row begin
if new.content != old.content then
insert into blogs values(null,new.content,new.id,null);
end if;
end//
delimiter ;
View Code

 -------------------------------------------------------事务---------------------------------------------

#MySQL 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。
        #1、在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
        #2、事务用来管理insert,update,delete语句    
        #3、事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行
           
mysql> create table user(
    -> id int primary key auto_increment,
    -> name char(32),
    -> balance int
    -> );

mysql> insert into user(name,balance)
    -> values
    -> ('hby',1000),
    -> ('pdun',1000),
    -> ('lb',1000);
准备数据
#start transaction;            开启事务

update user set balance = balance-100 where name = 'hby';
update user set balance = balance-100 where name = 'pdun';   

#rollback;

#commit;

------------------------------------------------------------------------

#start transaction;   

update user set balance = balance-100 where name = 'hby';
update user set balance = balance+100 where name = 'pdun';   

#savepoint p;

update user set balance = balance+100 where name = 'pdun';  

#rollback to p;
View Code

猜你喜欢

转载自www.cnblogs.com/pdun/p/10565636.html