MySQL 视图、索引、外键关联策略


 

视图

视图是一张虚表,将查询结果集保存起来,作为视图使用。实际存在的表叫作基本表。
 

视图的作用

  • 提高安全性。grant授权用户只能操作视图,通过视图来操作基本表,可以保护基本表中的数据
  • 提高查询性能。视图只是基本表的一部分,查视图比查全表快。尤其是多表查询的时候,查视图一张表比连接多张表查询要快很多

 

视图常用操作

-- 创建视图,as指定结果集,假设cs系的id是1
create view view_dep_cs as (select * from tb_student where dep_id=1);  -- 可以把这个视图作为cs系学生信息表来使用


-- 修改视图定义,用新结果集覆盖原来的结果集。如果视图不存在,会自动创建
create or replace view view_cs_dep as (select id,name from tb_student where dep_id=1);  


-- 从视图查询数据
select * from view_dep_cs where name='chy';  --查询cs系名字是chy的学生


-- 删除视图
drop view view_cs_dep;

 

创建视图的完整语法

create [algorithm=merge] view view_dep_cs as (select * from tb_student where dep_id=1) [with check option] ;

algorithm指定视图执行机制,有3个可选的值

1、merge 合并

不创建临时表,执行时会先用视图定义替换视图名,每次都是操作基本表,并不会提高查询性能,但可以增改删查。
 

2、temptable 临时表

把结果集保存为临时表,每次操作的都是临时表,可以提高查询性能,但只读,不能增删改。
 

3、undefined 未定义
不指定algorithm就是undefined,使用数据库设置的默认值,mysql默认使用merge。

 

如果使用merge,还可以设置一个可选参数:with check option 检查条件。

创建视图时设置了条件where dep_id=1,即视图中的记录都是dep_id=1的。

如果指定了with check option,往视图中插入、更新记录时,都要满足记录的dep_id=1这个条件,否则不执行操作;如果不指定with check option,则不要求dep_id=1。

使用merge时往往要设置with check option。

 

不可更新的视图

即使使用merge,也不一定可以进行增删改,as指定视图数据来源,如果视图来源中使用了一下任一项,则创建的视图只读(只能查询)、不能增删改

  • 聚合函数
  • group by子句
  • having子句
  • distinct关键字
  • union运算符
  • from来源于多个表或者来源于不可更新的视图

一句话:不是直接来源于一个基本表的视图,则该视图只读、不能更新视图数据。

 

索引

不使用索引时,要操作某些记录,需要遍历整张表来找到匹配的记录,时间开销大。

索引相当于数据表的目录,根据目录可直接定位到章节,根据索引可直接定位到数据表的记录,无需遍历整张表。

 

索引的优缺点

  • 极大提高了检索速度,尤其是记录数很多的时候(优)
  • 索引也是一张表,要占硬盘空间,有额外的空间开销(缺)
  • 对基本表进行增改删时会同步到索引(维护索引),有额外的时间、资源开销(缺)

相较于优点,索引的缺点微不足道。

 

常见的几种索引

  • 单值索引:索引中只包含数据表的一列(一个字段)
  • 唯一索引:索引中列的值唯一,一般是数据表的主键列
  • 复合索引:也叫作联合索引,索引中包含数据表的多个列
  • 全文索引:只能对MyISAM引擎的表使用,且索引中的列要是char、varchar、text等文本类型

 

索引常用操作

create index index_ts on tb_user(id,name);  -- on指定使用哪张表的哪些字段来创建索引。经常使用学号、姓名定位学生(记录),所以使用这2列创建索引
 
show index from tb_student;  -- 查看某个表上所有的索引
 
drop index index_ts on tb_student;  -- 删除索引

索引、视图都可以在数据库管理工具(比如Navicat)中直接操作。索引是在 “设计表” 中操作的。

 

常用的索引方式

1、b+树(最常用)

eg. 以id字段创建索引,假设有7条记录,id 1~7
在这里插入图片描述
查找id=7的记录的地址:4 -> 6 -> 7
 

2、hash  通过hash值一次直接找到记录的地址

eg. 使用id字段建立索引,查找id=7的记录:计算7的hash值 -> 根据hash值直接确定记录在表中的位置。
 

b+树要一级一级地找,hash直接定位,效率远高于btree。但一般都是使用b+树,因为大多数存储引擎都支持b+树,hash只有memory存储引擎支持。

 

哪些字段适合创建索引?

  • 主键
  • 外键
  • 频繁作为条件的字段。eg. 经常要用where name=’ ',那就给name字段创建索引
  • group by分组使用的字段
  • order by排序使用的字段
  • 统计(聚合函数)使用的字段

 

建立索引有额外的空间开销,增改删时维护索引也有额外的时间开销,记录数少的表没必要创建索引;频繁增改删的字段,维护索引开销大,不适合用来创建索引。

添加主键时,会自动给主键列创建唯一索引(Unique);添加外键时,会自动给外键列创建普通索引(Normal)。

创建索引后,从表中找匹配的记录时会自动选择合适的索引来使用,不需要我们指定索引。

 

外键关联策略

eg. tb_order通过外键user_id关联tb_user的主键id,当update、delete tb_user的id时,如何处理与之对应的tb_order中的记录?
在这里插入图片描述
设计外键时,mysql提供了4种外键关联策略

1、RESTRICT  限制(默认)

如果有外键关联了tb_user的id,则tb_user不能删除被关联的记录、不能更新关联记录id字段的值(会报错)。

如果要删除记录、更新id字段的值,需要先切断关联关系,比如先删除tb_order中与之关联的记录、或者把相关记录外键字段的值置为null。

 

2、CASCADE  级联(最常用)

删除tb_user中的记录时,会自动删除tb_order中与之关联的记录;修改tb_user中id字段的值时,会自动修改tb_order中与之关联的记录的外键字段的值(同步变化)。

 

3、NO ACTION  什么都不做

删除、更新tb_user中的user_id字段的值时,tb_order中与之关联的记录不作任何处理。此种策略需要存储引擎支持,如果存储引擎不支持,会自动换为RESTRICT。

 

4、SET NULL  置为NULL

删除tb_user的记录,或者更新id字段的值,会自动将tb_order中与之关联的记录的外键字段的值置为NULL。

这种方式有一个要求:设计tb_order时,外键字段不能用NOT NULL约束。

 

一般使用CASCADE,未设置外键关联策略时默认为RESTRICT(为了数据安全)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章