MySQL中索引、视图、触发器详解

版权声明:如果转载或使用本博客,请标明出处 https://blog.csdn.net/Black1499/article/details/82776818

一、索引

1.概述

  所有 MySQL 列类型都可以被索引,对相关列使用索引是提高 SELECT 操作性能的最佳途
径。根据存储引擎可以定义每个表的最大索引数和最大索引长度,每种存储引擎(如 MyISAM、
InnoDB、BDB、MEMORY 等)对每个表至少支持 16 个索引,总索引长度至少为 256 字节。
大多数存储引擎有更高的限制。
一个表的索引,就好比一本书的目录。有了目录,查询速度自然会大大加快。

2.语法

创建:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
	[USING index_type]
	ON tbl_name (index_col_name,...)

index_col_name:
	col_name [(length)] [ASC | DESC]

删除:

DROP INDEX index_name ON tbl_name

3. 案例实现

创建:

create index index_book on book_info(book_name);

删除:

drop index index_book on book_info;

4:使用原则

  • 搜索的索引列,不一定是所要选择的列。 换句话说,最适合索引的列是出现在 WHERE
    子句中的列,或连接子句中指定的列,而不是出现在 SELECT 关键字后的选择列表中的列。

  • 使用惟一索引。 索引的列的基数越大,索引的效果越好。例如,存放出生日期的列具有不同值,很容易区分各行。

  • 使用短索引。 如果对字符串列进行索引,应该指定一个前缀长度,只要有可能就应
    该这样做。这样做比对整个列进行索引的速度更快。

  • 利用最左前缀。 在创建一个 n 列的索引时,实际是创建了 MySQL 可利用的 n 个索引。
    多列索引可起几个索引的作用,因为可利用索引中最左边的列集来匹配行。这样的列集称为
    最左前缀。

  • 不要过度索引。 每个索引都会占用你的磁盘空间,每个表跟新的时候也需要更新索引。索引太多时,mysql可能会选择不到适合的索引,只保留有用的索引,才可优化查询速度。

二、视图

1.概述

  视图(View)是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的。视图并
不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时
动态生成的。简单来说,视图就是呈现给用户数据的一个虚拟表,只能查看,不会对原表产生任何影响。

2.不可更新的视图

  MySQL 视图的定义有一些限制,例如,在 FROM 关键字后面不能包含子查询,这和其他数据库是不同的,如果视图是从其他数据库迁移过来的,那么可能需要因此做一些改动,可以将子查询的内容先定义成一个视图,然后对该视图再创建视图就可以实现类似的功能了。视图的可更新性和视图中查询的定义有关系,以下类型的视图是不可更新的。

  • 包含以下关键字的 SQL 语句:聚合函数(SUM、MIN、MAX、COUNT 等)、DISTINCT、GROUP
    BY、HAVING、UNION 或者 UNION ALL。
  • 常量视图。
  • SELECT 中包含子查询。
  • JION。
  • FROM 一个不能更新的视图。
  • WHERE 字句的子查询引用了 FROM 字句中的表。

3.语法

创建:

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
	VIEW view_name [(column_list)]
	AS select_statement
	[WITH [CASCADED | LOCAL] CHECK OPTION]

修改:

ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
	VIEW view_name [(column_list)]
	AS select_statement
	[WITH [CASCADED | LOCAL] CHECK OPTION]

删除:

DROP VIEW [IF EXISTS] view_name [, view_name] ...[RESTRICT | CASCADE]

4.案例

创建:

create view book_view as
	select * from book_info b 
	inner join press_info p
	on b.press_id = p.press_id

删除:

drop view book_view

三、触发器

1.概述

  触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性。

2.语法

创建:

CREATE TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt

删除:

DROP TRIGGER [schema_name.]trigger_name

查看触发器:

-- 第一种,系统自带
show triggers \G;
-- 第二种,查看方式是查询系统表的 information_schema.triggers 表
desc triggers;

注意: 触发器只能创建在永久表(Permanent Table)上,不能对临时表(Temporary Table)创建触发器。

其中 triggertime 是触发器的触发时间,可以是 BEFORE 或者 AFTER,BEFORE 的含义指在检
查约束前触发,而 AFTER 是在检查约束后触发。
而 triggerevent 就是触发器的触发事件,可以是 INSERT、UPDATE 或者 DELETE。

3.案例

-- 每更新一次press_info表的数据,都向t_log表插入一条操作数据
create trigger tri_updinfo
after update on press_info for each row
	insert into t_log (notes) values ('update press_info');
end;

4.触发器的使用

触发器执行的语句有以下两个限制。

  • 触发程序不能调用将数据返回客户端的存储程序,也不能使用采用 CALL 语句的动态 SQL
    语句,但是允许存储程序通过参数将数据返回触发程序。也就是存储过程或者函数通过 OUT
    或者 INOUT 类型的参数将数据返回触发器是可以的,但是不能调用直接返回数据的过程。
  • 不能在触发器中使用以显式或隐式方式开始或结束事务的语句,如 START TRANSACTION、
    COMMIT 或 ROLLBACK。

MySQL 的触发器是按照 BEFORE 触发器、行操作、AFTER 触发器的顺序执行的,其中任何一
步操作发生错误都不会继续执行剩下的操作。如果是对事务表进行的操作,那么会整个作为
一个事务被回滚(Rollback),但是如果是对非事务表进行的操作,那么已经更新的记录将无
法回滚,这也是设计触发器的时候需要注意的问题。

5.小结

需要注意的是触发器是行触发的,每次增加、修改或者删除记录都会触发进行处理,编写过于复杂的触发器或者增加过多的触发器对记录的插入、更新、删除操作肯定会有比较严重的影响,因此数据库设
计的时候要有所考虑,不要将应用的处理逻辑过多的依赖于触发器来处理

猜你喜欢

转载自blog.csdn.net/Black1499/article/details/82776818