一 mysql视图
1 视图的目的:
让同一个数据库被访问时,对于不同的登录帐号,显示不同的数据信息
2 视图的优点:
1)数据独立: 一旦视图结构确定,可以屏蔽表结构对用户的影响
2)安全: 用户只能看到视图中的数据
3)简单: 用户不需要关心视图中的数据如何查询获得,视图中的数据已经是经过筛选好的符合条件的结果集
3 视图使用的限制:
不能在视图上创建索引
在视图的FROM子句中不使用子查询
4 视图的使用:
1)创建一个视图:
create view v1 as select * from user;
create view v2(vname,vgid) as select user,uid from user;
如果在视图表中不定义字段名,那么默认为基表的字段名
如果需要定义字段名。字段数量需要与基表一样。
2)查看所有表状态
mysql> show table status\G;
Comment: VIEW
comment字段的值为view的为视图
comment字段值为空时为基表
3)显示创建视图v1的命令:
mysql> show create view v1\G;
mysql> show table status where comment="VIEW"\G;
在正常情况下,修改基表里的数据,视图里的数据会跟着改变
修改视图里的数据,基表里的数据也会改变
当创建基表的时候如果有指定条件,那么在修改数据时,只要符合条件的数据都会在
视图中显示,不符合条件的不会在基表中显示
4)or replace 覆盖创建视图选项(当创建的视图名已存在,该选项可以覆盖)
基于多表查询时,字段名有重复时,必须给视图里的字段取名
mysql> create table t1 select user,uid,shell from user limit 3;
Query OK, 3 rows affected (0.34 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> create table t2 select user,uid,homedir,shell from user limit 5;
Query OK, 5 rows affected (0.57 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from t1;
+--------+------+---------------+
| user | uid | shell |
+--------+------+---------------+
| root | 0 | /bin/bash |
| bin | 1 | /sbin/nologin |
| daemon | 2 | /sbin/nologin |
+--------+------+---------------+
3 rows in set (0.00 sec)
mysql> select * from t2;
+--------+------+----------------+---------------+
| user | uid | homedir | shell |
+--------+------+----------------+---------------+
| root | 0 | /root | /bin/bash |
| bin | 1 | /bin | /sbin/nologin |
| daemon | 2 | /sbin | /sbin/nologin |
| adm | 3 | /var/adm | /sbin/nologin |
| lp | 4 | /var/spool/lpd | /sbin/nologin |
+--------+------+----------------+---------------+
mysql> select * from t1,t2 where t1.user=t2.user;
+--------+------+---------------+--------+------+---------+---------------+
| user | uid | shell | user | uid | homedir | shell |
+--------+------+---------------+--------+------+---------+---------------+
| root | 0 | /bin/bash | root | 0 | /root | /bin/bash |
| bin | 1 | /sbin/nologin | bin | 1 | /bin | /sbin/nologin |
| daemon | 2 | /sbin/nologin | daemon | 2 | /sbin | /sbin/nologin |
+--------+------+---------------+--------+------+---------+---------------+
3 rows in set (0.00 sec)
mysql> create view v3 as select * from t1,t2 where t1.user=t2.user;
ERROR 1060 (42S21): Duplicate column name ‘user’
现在字段名重复,创建视图报错
mysql> create or replace view v3(t1user,t1uid,t1shell,t2user,t2uid,t2homedir) as select * from t1,t2 where t1.user=t2.user;
mysql> select * from v3;
+--------+-------+---------------+--------+-------+-----------+
| t1user | t1uid | t1shell | t2user | t2uid | t2homedir |
+--------+-------+---------------+--------+-------+-----------+
| root | 0 | /bin/bash | root | 0 | /root |
| bin | 1 | /sbin/nologin | bin | 1 | /bin |
| daemon | 2 | /sbin/nologin | daemon | 2 | /sbin |
+--------+-------+---------------+--------+-------+-----------+
3 rows in set (0.01 sec)
mysql> create view v8 as select a.user,b.homedir from t1 a right join t2 b on a.uid=b.uid;
Query OK, 0 rows affected (0.02 sec)
mysql> select * from v8;
+--------+----------------+
| user | homedir |
+--------+----------------+
| root | /root |
| bin | /bin |
| daemon | /sbin |
| NULL | /var/adm |
| NULL | /var/spool/lpd |
+--------+----------------+
关于算法:
算法未定义时,值为UNDEFIBED 默认为 merge替换方式
temptables 具体化方式
具体化方式:先执行select基表 ,再执行查询视图 两次 速度慢
merge 替换方式只查询视图,速度块。
关于视图限制:
with check option 选项决定检查的范围
local 仅检查当前视图的限制
当没有指定限制时:默认为cascaded 同时满足基表的限制(默认值)
视图的基表也可以是一个视图 (所以此视图作为基表可以有限制)
如果修改视图未加限制时,视图内字段的值可以随意修改,但是当字段的值超出了本视图的限制范围,那么该字段在此视图中将不可见。
二 mysql存储过程:
存储过程,相当于是mysql语句组成的脚本
–指的是数据库中保存的一系列SQL命令的集合
–可以在存储过程中使用变量,条件,流程控制等
存储过程优点:
–提高性能
–可减轻网络负担
–可以防止对表的直接访问
–避免重复编写SQL操作
1 创建存储过程
1)在库里创建存储过程
delimiter
英 [ dɪ’lɪmɪtə ]美 [ dɪ’lɪmɪtə ]
n. 定界符,分隔符;
procedure
英 [ prəˈsi:dʒə® ]美 [ prəˈsidʒɚ ]
n. 程序,手续;工序,过程,步骤;诉讼程序,(议会的)议事程序;〈罕〉进行;
2)基本格式:
delimiter //
create procedure f()
begin
select * from db9.user limit 3;
create table if not existsdb9.a(id int);
end
//
mysql> create procedure f() begin select * from db9.user limit 3; create table if not exists a(id int); end //
将分隔符改回来
delimiter ;
调用 call f()
3)显示当前库下的存储状态
show procedure status;
select db,name,type from mysql.proc where name="存储过程名"
mysql> select body from mysql.proc where name="f"\G; 查看存储过程f的具体SQL语句
mysql> select db,name,type,body from mysql.proc where name="f";
4)创建f2存储过程,功能显示user表中 shell是/bin/bash用户的个数,调用存储过程f2:
mysql> delimiter //
mysql> create procedure f2() begin select count(user) from db9.user where shell="/bin/bash"; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call f2;
+-------------+
| count(user) |
+-------------+
| 3 |
+-------------+
1 row in set (0.00 sec)
三 mysql变量类型
会话变量 全局变量: 会话变量的全局变量叫系统变量,使用set命令定义,全局变量的修改会影响到整个服务器,但是对会话变量的修改,只会影响到当前的会话 select @@localhost
用户变量: 在客户端连接到数据库服务的整个过程中都是有效的,当当前连接断开后所有用户变量失效 定义 set @变量名=值 输出 select @变量名
局部变量: 存储过程中的begin/end,其有效范围仅限于该语句块中,语句块执行完毕后,变量失效。 declare 专门用来定义局部变量
注意: 局部变量和参数变量调用时,变量名前不需要加@
1 一次数据库的连接为一次会话。会话变量session只对当前连接有效
ysql> set session sort_buffer_size = 40000;
Query OK, 0 rows affected (0.00 sec)
2 全局变量
mysql> show global variables like "%connect%";
+-----------------------------------------------+-------------------+
| Variable_name | Value |
+-----------------------------------------------+-------------------+
| character_set_connection | latin1 |
| collation_connection | latin1_swedish_ci |
| connect_timeout | 10 |
| disconnect_on_expired_password | ON |
| init_connect | |
| max_connect_errors | 100 |
| max_connections | 151 |
| max_user_connections | 0 |
| performance_schema_session_connect_attrs_size | 512 |
+-----------------------------------------------+-------------------+
9 rows in set (0.00 sec)
select @@hostname
3 用户变量(自定义变量):
mysql> set @x=9;
Query OK, 0 rows affected (0.00 sec)
mysql> select @x;
+------+
| @x |
+------+
| 9 |
+------+
1 row in set (0.00 sec)
mysql> set @name="yaya";
mysql> select @name;
+-------+
| @name |
+-------+
| yaya |
+-------+
4 局部变量:
定义在存储过程里,只在存储过程执行时有效
mysql> delimiter //
mysql> create procedure f4() begin declare x int; set x=2; select x; select * from user where uid=x; end //
mysql> delimiter ;
mysql> call f4()
-> ;
+------+
| x |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
+----+--------+--------+------+------+--------+---------+---------------+
| id | user | passwd | uid | git | commet | homedir | shell |
+----+--------+--------+------+------+--------+---------+---------------+
| 3 | daemon | x | 2 | 2 | daemon | /sbin | /sbin/nologin |
+----+--------+--------+------+------+--------+---------+---------------+
局部变量如果和用户变量同名,它们之间不会有任何影响
在语句块中,同名的变量,后赋值的生效。
注意:declare在语句块中定义变量时需要一块定义,不要跳行,变量前不需要加@符号
mysql> delimiter //
mysql> create procedure f7() begin declare y int default 1; select y; select count(id) into y from user; select y; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call f7;
+------+
| y |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
+------+
| y |
+------+
| 42 |
+------+
1 row in set (0.00 sec)
将查询结果赋值给自定义变量(用户变量):
mysql> select user into @x from user where id=1;
Query OK, 1 row affected (0.00 sec)
mysql> select @x;
+------+
| @x |
+------+
| root |
+------+
1 row in set (0.00 sec)
5 参数类型:
可以有多个参数,结尾以逗号分隔,结构:(类型 参数名 数据类型)
如果不指定类型,默认为In类型
in 输入参数 :作用是给存储过程传值,必须在调用存储过程时赋值(传参),在存储过程中该参数的值不允许修改,默认类型为in
out 输出参数 : 该值可在存储过程内部被改变,并可返回
inout 输入/输出参数 : 调用时指定,并且可被改变和返回。
1)案例 in :
mysql> delimiter //
mysql> create procedure shelle(in shellname char(30)) begin declare x int default 0;select x; select count(user) into x from user where shell=shellname; select x; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call shelle("/sbin/nologin");
+------+
| x |
+------+
| 0 |
+------+
1 row in set (0.01 sec)
+------+
| x |
+------+
| 34 |
+------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> call shelle("/bin/bash");
+------+
| x |
+------+
| 0 |
+------+
1 row in set (0.00 sec)
+------+
| x |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
2)Out类型:
Outl类型在调用变量时不能直接给值,需要给一个变量来做占位符,无论这个变量是否有值 ,out类型的参数用于接收存储过程执行的结果。
mysql> delimiter //
mysql> create procedure p1(in shellname char(30),out number int) begin select count(user) into number from user where shell=shellname; select number; end //
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
mysql> call p1("/bin/bash",@z);
+--------+
| number |
+--------+
| 3 |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
~~~~~~~~~~~~~~~~~
mysql> call p1("/sbin/nologin",@q); //变量随意调用,但必须是一个变量
+--------+
| number |
+--------+
| 34 |
+--------+
1 row in set (0.00 sec)
3)in /out 类型:
存储过程调用时参数为一个有值的变量
mysql> delimiter //
mysql> create procedure p4(inout x char(30)) begin select x; select user into x from user where id=1;select x; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> set @a="qqq";
mysql> call p4(@a);
+------+
| x |
+------+
| qqq |
+------+
1 row in set (0.00 sec)
+------+
| x |
+------+
| root |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> create procedure say3(in bash char(20),in nologin char(20),out x int,out y int) begin declare z int; set z=0; select count(user) into x from user where shell=bash; select count(user) into y from user where shell=nologin; set z=x+y; select z; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call say3("/bin/bash","/sbin/nologin",@q,@w);
+------+
| z |
+------+
| 37 |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
7 流程控制
1)条件判断
××单分支
begin
if 条件测试 then
代码
end fi ;
end
××双分支
begin
if条件测试
代码1
else
代码2
end if
end
mysql> delimiter //
mysql> create procedure say4(in x int) begin if 1=x then
-> select * from user limit 1; else select * from user limit 1,1; end if ; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call say4(1);
+----+------+--------+------+------+--------+---------+-----------+
| id | user | passwd | uid | git | commet | homedir | shell |
+----+------+--------+------+------+--------+---------+-----------+
| 1 | root | x | 0 | 0 | root | /root | /bin/bash |
+----+------+--------+------+------+--------+---------+-----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> call say4(2);
+----+------+--------+------+------+--------+---------+---------------+
| id | user | passwd | uid | git | commet | homedir | shell |
+----+------+--------+------+------+--------+---------+---------------+
| 2 | bin | x | 1 | 1 | bin | /bin | /sbin/nologin |
+----+------+--------+------+------+--------+---------+---------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
定义名称为p3的存储过程,用户可以自定义显示user表记录的行数,若调用时用户没有输入行数,默认显示第1条记录
mysql> create procedure p3(in x char(5))
begin
if x is null then
set x=1;
select * from user where id=x;
else
select x;
select * from user where id=x;
end if;
end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call p3(null) ;
+----+------+----------+------+------+---------+---------+-----------+
| id | name | password | uid | gid | comment | homedir | shell |
+----+------+----------+------+------+---------+---------+-----------+
| 1 | root | x | 0 | 0 | root | /root | /bin/bash |
+----+------+----------+------+------+---------+---------+-----------+
mysql> call p3(40);
+------+
| x |
+------+
| 40 |
+------+
1 row in set (0.00 sec)
+----+------+----------+------+------+---------+------------+-----------+
| id | name | password | uid | gid | comment | homedir | shell |
+----+------+----------+------+------+---------+------------+-----------+
| 40 | lisi | x | 1000 | 1000 | lisi | /home/lisi | /bin/bash |
+----+------+----------+------+------+---------+------------+-----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 s
ec)
2)while循环结构
while 条件式循环 --反复测试条件,只要成立就执行命令序列
结构:
begin
while 条件判断 do
循环体
end while;
end //;
mysql> delimiter //
mysql> create procedure say7() begin declare x int default 1; while x<=10 do select * from user limit 1,1;set x=x+1; end while; end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call say7();
3)loop死循环–无条件,无限执行某一段代码
结构:
loop
循环体
end loop;
mysql> delimiter //
mysql> create procedure say8() begin declare x int default 1; loop select x; end loop; end //
mysql> delimiter ;
mysql> call say8();
4)repeat 条件式循环–当条件成立时结束循环(结构与while循环)
结构:
repeat
循环体
until 条件判断
end repeat
mysql> delimiter //
mysql> create procedure say9() begin declare x int default 1; repeat select * from user limit 1;set x=x+1; until x>=6 end repeat; end //
mysql> delimiter ;
mysql> call say9();
5)流程控制函数,控制循环结构的执行:
–leave 标签名 //跳出循环
–iterate 标签名 //放弃本次循环,执行下一次循环
##输出0-10 当值为4时跳过。(loab1为自己随意取的标签名)
mysql> delimiter //
mysql> create procedure say17()
begin declare x int default 0;
loab1:while x<=10 do
if x=4 then
set x=x+1; iterate loab1;
end if;
select x; set x=x+1;
end while;
end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call say17;
##输出1-15 当值为4时跳过,当值为13的时候结束循环 (loab1为自己随意取的标签名)
mysql> delimiter //
mysql> create procedure say21() begin declare x int default 1; loab1:while x<=15 do if x=8 then set x=x+1; iterate loab1; end if; select x; set x=x+1; if x=13 then leave loab1; end if; end while; end //
mysql> delimiter ;
mysql> call say20;