视图是一张虚表,将查询结果集保存起来,作为视图使用。实际存在的表叫作基本表。
视图的作用
视图常用操作
-- 创建视图,as指定结果集,假设cs系的id是1
create view view_dep_cs as (select * from tb_student where dep_id=1); -- 可以把这个视图作为cs系学生信息表来使用
-- 修改视图定义,用新结果集覆盖原来的结果集。如果视图不存在,会自动创建
create or replace view view_dep_cs as (select id,name from tb_student where dep_id=1);
-- 从视图查询数据
select * from view_dep_cs where name='chy'; --查询cs系名字是chy的学生
-- 删除视图
drop view view_dep_cs;
创建视图的完整语法
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指定视图数据来源,如果视图来源中使用了一下任一项,则创建的视图只读(只能查询)、不能增删改
一句话:不是直接来源于一个基本表的视图,则该视图只读、不能更新视图数据。
不使用索引时,要操作某些记录,需要遍历整张表来找到匹配的记录,时间开销大。
索引相当于数据表的目录,根据目录可直接定位到章节,根据索引可直接定位到数据表的记录,无需遍历整张表。
索引的优缺点
相较于优点,索引的缺点微不足道。
常见的几种索引
索引常用操作
create index index_ts on tb_student(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存储引擎支持。
哪些字段适合创建索引?
建立索引有额外的空间开销,增改删时维护索引也有额外的时间开销,记录数少的表没必要创建索引;频繁增改删的字段,维护索引开销大,不适合用来创建索引。
添加主键时,会自动给主键列创建唯一索引(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(为了数据安全)。