MySQL之视图,索引,存储过程,触发器--实操

发布时间 2023-06-02 09:43:35作者: ~java小白~

一.视图

什么是视图?

  1. 视图是一个虚拟表,其内容由查询定义。
  2. 同真实的表一样,视图包含系列带有名称的列和行数据。
  3. 行和列数据来自定义视图的查询所引用的表,并且在引用视图时动态生成。
  4. 简单的来说视图是由select结果组成的表。

视图的出现其实优化了MySQL对用户权限的管理,我们在以前学的用户管理,在高级用户上也会对每个用户创建给予一些权限,

不知道有没有小伙伴注意到,在用户注册是给予的权限其实是一张张表的分发的,它的基本授予单位是表,也就是你可以对整个表进行增,删,改,查的任 一的权力

对于一般的表可能是够用了,但是对于重要的表是十分不妥的,比如  :用户登录表 对于运维人员来说,可能只用查看用户名和用户等级就差不多了,然后按特征分配服务

但是只要是个运维人员,都给select 权力给用户登录表,运维人员知道重要的用户密码有什么用呢?或者说每个运维人员知道所有用户的密码这妥当嘛

所以视图可以筛选其中的列,可以以最小分量的形式给开发团队授权,就比如运维人员,他们的权限只用知道 用户名和用户等级所在的列信息就可以了,没必要整个用户表都知道

1.视图的创建

命令格式:

Create  or replace  View  (视图名称)

as  子查询语句(视图要显示的数据范围)

[with check  option ];

视图名称后面可以跟要显示的数据列,但是必须和子查询中显示的列相等,不同则无法匹配

or  replace :表示的是有相同的视图名就替换它

注意点:

  • 视图是基于基本表数据的,对视图的更改,在成功的情况下,是对基本表的更改,视图只是用于隐藏一些不可见的列,并不是一个新的表实例,最后的操作都是基本表
  • 一旦视图创建完成,对视图的操作关键字和对表操作的关键字都是一样的(select,insert ,update ,delete )

 2.视图的增删改查

视图的插入(insert 语句):

 视图的更改(update语句):

 视图的查询(select语句):

 视图的删除(delete语句):

视图的操作成功了都是在基本表的操作!!!

视图不可操作的情况:

  • 含有聚合函数
  • distinct 关键字修饰
  • group by 修饰
  • order by 修饰
  • having 修饰
  • union运算符(联合查询)
  • from子句含有多个表

 3.视图的with check option检查选项

视图的检查选项一共有两种:Cascade  Local  

它们两种关键字是一定要在基于视图建立起来的视图,才需要,如果是基于表建立起来的视图 只需要加上 with check option

加上检查选项以后,我们要对视图操作必须要满足创建该视图子查询的  where 条件,否则不能更改

Cascade:

被cascade修饰的视图,它的检查范围是相互关联的,是一级一级的检查的,也叫做级联,当某个视图被此关键字修饰,不仅要检查自己视图的范围,还要对子查询中的视图进行检查,看看范围是否合乎要求

只要自己被标记,从自己开始一直往下检查where 子句的条件,一个不满足就不能更改

 

Local:

local关键字只会检查被标识的视图,对于未标识检查选项的视图不会检查,

但是他会一直去查看所构成自己所用到的视图有没有检查选项,这一步是有无检查选项都要经历的,万一上一级视图有检查选项呢?

省流:检查带有local的视图

 对于local检查选项和cascade,可以看的出cascade检查选项要麻烦很多,尤其是我们在实际开发中有很多视图的情况,更加会混淆,根本不知道那个视图不满足要求,所以尽量少用cascade,要使用就是用local可以很明显的知道是哪里没有满足条件

这也是为什么阿里巴巴明文禁止使用级联的原因,所以道理都是在实践中探索出来的。

二.索引

 什么是索引?

索引  ------是一种提升查找速度的机制

 关于索引的详细解释,在我MySQL之B+树中已经讲过了,这里我们主要看看索引的实操

索引的分类:

1.普通索引(index)

它是最基本的索引类型,它没有唯一性等要求,可以提升数据的检索效率,索引都会单独生成一个表文件

2.唯一性索引(unique)

其它的和基本索引差不多,但是唯一性索引的值都是唯一的或者为空

3.主键(primary key)

主键是表中唯一,且不为空,它在一个表中只能有一个

4.全文索引(Fulltext)

全文索引如其名一样,可以进行全文搜索,全文索引只能在varchar和text类型的文本上创建,并且引擎为MyISAM

创建索引:

命令格式:

Create [ unique  |   fulltext]  index  索引名

on  表名(列名(长度)[  ASC |  DESC  ])

默认升序排序

create index :创建普通索引

create unique  index :创建唯一索引

create  fulltext  index :创建全文索引

全文索引要在MyISAM引擎中创建,我们使用的都是InnoDB,所以就不演示了

create  index不能创建主键索引

Alter Table 语句创建索引:

命令格式:

Alter Table  表名

add   index   索引名(索引列)             //普通索引

add   primary  key (索引列)              // 主键索引

add   unique index  索引名 (索引列)//唯一性索引

add  fulltext index   索引名 (索引列)//全文索引

从上面的命令我们就可以看到其实我们是可以用alter table命令创建主键的,这是比create  index高级一点的地方

并且alter table语句可连续创建,只要 add 命令写完整,并且使用英文逗号分割就可以了

alter table的  单行  命令创建:

 alter table的  多行  命令创建:

 索引的删除:

命令格式:

drop  index  索引名  on  表名

除了主键外,删除索引统一使用index,不需要加上 unique,fulltext,但是此命令删除不了主键

 使用alter table 删除索引

命令格式:

Alter  Table  表名

drop  primariy  key      // 删除主键

drop  index   索引名    // 删除索引

删除命令和添加索引命令一样,只要drop命令写完整了,就可以连续删除了

alter  table 的  单行  命令删除:

 alter table的  多行  命令删除:

 参照完整性约束:

 参照完整性是广泛的存在关系型数据库当中的,在这种数据库中,两个或多个表它们之间其实是有联系的,可以通过这些关系一个表在另外的一个表中完成一些映射关系

它在数据库中指的是实体与另一个实体之间的联系

通常参数完整性我们使用外键来标识,参照的表叫子表,被参照的表叫父表

建立了外键,子表中的字段要么为父表中的分量,要么为null

一旦存在外键后两个表就绑定了联系,对于子表的插入,会受限制,当父表的主键没有的分量,子表是无法插入的,也叫此时没有参照关系

对于父表也是,对于父表的删除和更改也会受到限制,要么不能删除,要么和子表一起更改,要么给子表设置为null

外键设置命令格式:

Alter Table  表名

 add  Foreign ley  (子表列名)

References  父表名(父表被参照字段(长度)  [  ASC  |  DESC])

[  on  delete {   restrict  |  cascade  |  set NULL  |  no  action  }]

[  on  update {   restrict  |  cascade  |  set NULL  |  no  action  }  ]

父表的字段名为父表的主键

on  delete :父表分量删除时的选项

on  update:父表分量更改时的选项

restrict  |   no  action :父表的分量被参照时,要删除或更改时,不允许父表更改和删除

cascade :父表的分量被参照时,要删除或更改时,子表参照的分量和父表的分量进行同步更改

set  NULL :父表的分量被参照时,要删除或更改时,子表的参照分量直接置为NULL

 删除外键:

我们删除索引或者外键的时候都需要索引和外键名,但是一般我们并没有给外键命名,所以我们就需要使用:show  create  table  子表名  ,来查看建表时候的操作,也可以查看到外键名

外键删除命令格式:

Alter  table  表名

drop  foreign  key  外键名; 

语法都是alter  table 但是我们一定要知道外键名才能完成删除,不然是无法删除外键的

 使用外键以后,表的删除和更改可见的麻烦,所以在实际开发中应该尽量少用外键,尤其是大量的外键关联,对于关系模型,其实两个表的主键就能联系起来了,没必要使用外键

这也是阿里巴巴明文规定不允许使用外键的原因

三.存储过程

什么是存储过程? 

大多数 SQL 语句都是针对一个或多个表的单条语句。并非所有的操作都那么简单。经常会有一个完整的操作需要多条语句才能完成

存储过程简单来说,就是为以后的使用而保存的一条或多条 MySQL 语句的集合。可将其视为批处理文件。虽然他们的作用不仅限于批处理。

存储过程是为了减少服务器端和数据库端传输数据的优化,因为在大量的sql传输过程中其实有大量的语句重复,我们想,如果在数据库端有个模板供我们调用,每次传输只是参数的变动那不就万事大吉了嘛

这就是存储过程的思想:

 通过上面的图片我们在每次传输的过程都是一条完整的sql,更重要的是每次传输的sql都是一样的,只是参数在变化,这样是及其浪费资源的,所以我们要优化传输

 这就是存储过程的产生原因

存储过程的特点:封装,复用,可以接受参数,也可以返回数据,减少网络交互,效率提升

存储过程的基本语法:

命令格式:

Create    Procedure   存储过程名称(参数名称)

Begin

sql 语句

End;

调用存储过程:

Call  存储过程名称(参数);

 图片就是存储过程的实现,我们来说几个注意点:

  • 第一个红框是切换MySQL的sql语句结束符为$$
  • 第二个红框存储过程中的sql语句必须是英文分号结尾,它是一句完整的sql,但是分号原来是sql的结束,要是不用delimiter切换结束符就会导致命令提前结束,创建不成功,所以这就是为什么一开始我就切换了的原因(如果不是命令行的操作可以不用切换)
  • 第三个红框标识创建存储过程的命令完成了,我们该结束sql了,所以使用delimiter切换了的结束符
  • 第四个红框就是调用存储过程

查看存储过程:

命令格式:

select  * from  information_schema.routines  where routine_schema = 'XXX';   XXX为数据库名字

show  create  procedure  存储过程名;

删除存储过程:

命令格式:

drop  procedure  存储过程名;

变量之系统变量:

系统变量一共有种:一种是全局变量(global),一种是会话变量(session)

全局变量是:全部用户都可以使用并被限制的

会话变量是:自己和数据库端使用的和被限制的

查看系统变量:

命令格式:

show  [ global  |  session  ] variables ;                  // 查看所有系统变量,默认查找session

show  [ global  |  session  ] variables  like ' ... .' ;//模糊查找指定变量

select @@[  global  |  session ] 已知变量名 ;         //查找已知的变量

 设置系统变量的值:

命令格式:

set  [ global  |  session  ] 系统变量名 = 值 ; 

set  @@[ global  |  session  ] 系统变量名 = 值 ;

 变量之用户自定义变量:

用户自定义变量指的是用户根据自己的需求定义的变量,用户变量不用提前声明,用的时候直接使用“@变量名”,作用域为会话级别session

用户自定义的变量是一个 @ ,而系统变量是两个@@

命令格式:

set  @var_name = 值;                                        //  普通赋值

set  @var_name := 值;

select 字段名, into @var_name  from   表名;  // 对查询的结果字段映射到变量上

变量的使用:

命令格式:

select  @var_name

变量既可以是直接使用,也可以嵌套select结果映射,还可以直接赋值使用

变量之局部变量:

局部变量是定义在局部生效的变量,在访问前必须用  declare 关键字声明为局部变量,可以用于存储过程的输入输出的参数变量

它的作用域只在  begin  ......  end  之间

命令格式:

declare  变量名  变量类型  [ default ...] ;

局部变量必须使用declare关键字修饰,并且要有数据类型

赋值:

命令格式:

set  变量名 = 值;                                        //  普通赋值

set  变量名:= 值;

select 字段名, into 变量名  from   表名;  // 对查询的结果字段映射到变量上

存储过程之存储的变量: 

存储过程需要的传入的变量一共有三种类型:

  • IN :表示的是输入变量,需要调用存储过程的人进行传入
  • OUT:表示的是输出变量,需要调用者有一个变量来接受传回的值
  • InOut:表示的是输入输出变量,它即可以作为输入参数进行计算,也可以作为输出参数来回带结果

这三种变量广泛用于存储过程, 用于标识参数的使用范围

MySQL存储过程编程:

存储过程之  IF  判断:

命令格式:

IF  条件  then  ......;

elseif  条件  then  .......;

else .........;

end if;

注意:elseif必须连写

 存储过程之case条件判断:

命令格式:

case

when  条件  then  .....;

[ when  条件  then  .....;]

else .....;

end  case;

 存储过程之while循环:

命令格式:

while  条件  do

sql 语句......

end  while;

这里的while和编程语言中的一摸一样,会其一就会其二

 存储过程之repeat循环:

命令格式:

repeat

sel 语句.......

until  条件

end repeat;

repaet循环的逻辑和一般的逻辑不一样,它是条件为真的时候退出,条件为假的时候执行,until 子句没有分号

repeat会先执行一次,看是否满足条件,满足就退出循环,不满足条件继续执行

 存储过程之loop循环:

命令格式:

[  begin_lable :] loop

sql 语句......

end  loop lable;

leave  lable;   // 指定标记离开循环体

iterate  lable; //直接进入下一次循环

特别注意的是 loop没有退出循环的条件,如果没有配置 leave lable将会是一个死循环,建议一定每次使用loop的时候加上  leave  lable

 存储函数定义:

命令格式:

create  function  函数名(参数【也需要用in/out/inout修饰】)

returns  数据类型  NO sql / deterministic  /  reads sql data    // 必须写不然无法成功,一般选择deterministic

begin

sql语句.........

return  返回值;

end;

存储函数必须要有返回值,也就是调用者必须要要有变量来接受参数不然就会报错,根本执行不了

deterministic :相同的输入参数总是产生相同的结果

NO sql :不包括sql语句

reads sql data:包括读取数据的语句,但是不包括写入数据的语句

 四.触发器

什么是触发器?

触发器是一种用来保障参照完整性的特殊的存储过程,它维护不同表中数据间关系的有关规则。当对指定的表进行某种特定操作(如:Insert,Delete或Update)时,触发器产生作用。触发器可以调用存储过程。

触发器就和它的名字一样触发,触发,什么才能触发呢?

一般是一个触发器绑定的表有增,删,改的时候,触发器就会有一个行为

什么行为?什么语句触发?什么时候触发?都是开发者自定义的

接下来我们看看触发器的创建命令

注意下面强调的NEW和OLD关键字单独使用没有任何意义,需要使用NEW.cloum_name,OLD.cloum_name,关键字加列名才能生效

查看触发器

命令格式:

show  triggers;

触发器之insert型:

NEW关键字用于标识insert 语句将要或者已经更新的数据

命令格式:

create  trigger  trigger_name 

before/after   insert   on  table_name  for each row 

begin

sql语句......

trigger_stmt;

end;

关键词解释:

before/after :指的是触发器会在绑定表的sql执行前还是执行后插入

for  each  row :行级触发器,指的是每次只要是绑定表的一行增  /  删  /  改 都会触发

trigger_stmt :主要是指的  触发器的NEW和old关键字使用

 

触发器之update型:

OLD关键字表示修改前的数据,NEW表示修改之后的数据

命令格式:

create  trigger  trigger_name 

before/after   update on  table_name  for each row 

begin

sql语句......

trigger_stmt;

end;

触发器之delete型:

OLD关键字表示删除的数据

命令格式:

create  trigger  trigger_name 

before/after   delete on  table_name  for each row 

begin

sql语句......

trigger_stmt;

end;

 我的例子触发器触发的表都是test1,而触发器产生相应操作的表都是test2