一、视图

视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结果集,并可以将其当作表来使用。

  1. SELECT
  2. *
  3. FROM
  4. (
  5. SELECT
  6. nid,
  7. NAME
  8. FROM
  9. tb1
  10. WHERE
  11. nid > 2
  12. ) AS A
  13. WHERE
  14. A. NAME > 'alex';

临时表搜索

1、创建视图

  1. --格式:CREATE VIEW 视图名称 AS SQL语句
  2. CREATE VIEW v1 AS
  3. SELET nid,
  4. name
  5. FROM
  6. A
  7. WHERE
  8. nid > 4

2、删除视图

  1. --格式:DROP VIEW 视图名称
  2.  
  3. DROP VIEW v1

3、修改视图

  1. -- 格式:ALTER VIEW 视图名称 AS SQL语句
  2.  
  3. ALTER VIEW v1 AS
  4. SELET A.nid,
  5. B. NAME
  6. FROM
  7. A
  8. LEFT JOIN B ON A.id = B.nid
  9. LEFT JOIN C ON A.id = C.nid
  10. WHERE
  11. A.id > 2
  12. AND C.nid < 5

4、使用视图

  1. select * from v1

二、触发器

对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为。

1、创建基本语法

  1. # 插入前
  2. CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4. ...
  5. END
  6.  
  7. # 插入后
  8. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  9. BEGIN
  10. ...
  11. END
  12.  
  13. # 删除前
  14. CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
  15. BEGIN
  16. ...
  17. END
  18.  
  19. # 删除后
  20. CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
  21. BEGIN
  22. ...
  23. END
  24.  
  25. # 更新前
  26. CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
  27. BEGIN
  28. ...
  29. END
  30.  
  31. # 更新后
  32. CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
  33. BEGIN
  34. ...
  35. END
  1. delimiter //
  2. CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4.  
  5. IF NEW. NAME == 'alex' THEN
  6. INSERT INTO tb2 (NAME)
  7. VALUES
  8. ('aa')
  9. END
  10. END//
  11. delimiter ;

插入前触发器

  1. delimiter //
  2. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4. IF NEW. num = 666 THEN
  5. INSERT INTO tb2 (NAME)
  6. VALUES
  7. (''),
  8. ('') ;
  9. ELSEIF NEW. num = 555 THEN
  10. INSERT INTO tb2 (NAME)
  11. VALUES
  12. (''),
  13. ('') ;
  14. END IF;
  15. END//
  16. delimiter ;

后触发器

特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。

2、删除触发器

  1. DROP TRIGGER tri_after_insert_tb1;

3、使用触发器

触发器无法由用户直接调用,而是由于对表的【增/删/改】操作被动引发的。

  1. insert into tb1(num) values(666)

三、存储过程

存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行。

1、创建存储过程

  1. -- 创建存储过程
  2.  
  3. delimiter //
  4. create procedure p1()
  5. BEGIN
  6. select * from t1;
  7. END//
  8. delimiter ;
  9.  
  10. -- 执行存储过程
  11.  
  12. call p1()

对于存储过程,可以接收参数,其参数有三类:

  • in          仅用于传入参数用
  • out        仅用于返回值用
  • inout     既可以传入又可以当作返回值
  1. -- 创建存储过程
  2. delimiter \\
  3. create procedure p1(
  4. in i1 int,
  5. in i2 int,
  6. inout i3 int,
  7. out r1 int
  8. )
  9. BEGIN
  10. DECLARE temp1 int;
  11. DECLARE temp2 int default 0;
  12.  
  13. set temp1 = 1;
  14.  
  15. set r1 = i1 + i2 + temp1 + temp2;
  16.  
  17. set i3 = i3 + 100;
  18.  
  19. end\\
  20. delimiter ;
  21.  
  22. -- 执行存储过程
  23. set @t1 =4;
  24. set @t2 = 0;
  25. CALL p1 (1, 2 ,@t1, @t2);
  26. SELECT @t1,@t2;

有参存储过程

2、删除存储过程

  1. drop procedure proc_name;

3、执行存储过程

  1. -- 无参数
  2. call proc_name()
  3.  
  4. -- 有参数,全in
  5. call proc_name(1,2)
  6.  
  7. -- 有参数,有inoutinout
  8. set @t1=0;
  9. set @t2=3;
  10. call proc_name(1,2,@t1,@t2)
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import pymysql
  4.  
  5. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='t1')
  6. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  7. # 执行存储过程
  8. cursor.callproc('p1', args=(1, 22, 3, 4))
  9. # 获取执行完存储的参数
  10. cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
  11. result = cursor.fetchall()
  12.  
  13. conn.commit()
  14. cursor.close()
  15. conn.close()
  16.  
  17. print(result)

pysql执行存储过程

四、事务

事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

  1. delimiter \\
  2. create PROCEDURE p1(
  3. OUT p_return_code tinyint
  4. )
  5. BEGIN
  6. DECLARE exit handler for sqlexception
  7. BEGIN
  8. -- ERROR
  9. set p_return_code = 1;
  10. rollback;
  11. END;
  12.  
  13. DECLARE exit handler for sqlwarning
  14. BEGIN
  15. -- WARNING
  16. set p_return_code = 2;
  17. rollback;
  18. END;
  19.  
  20. START TRANSACTION;
  21. DELETE from tb1;
  22. insert into tb2(name)values('seven');
  23. COMMIT;
  24.  
  25. -- SUCCESS
  26. set p_return_code = 0;
  27.  
  28. END\\
  29. delimiter ;
  30. set @i =0;
  31. call p1(@i);
  32. select @i;

支持事务的存储过程

五、索引

索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。

  1. 30
  2.  
  3. 10 40
  4.  
  5. 5 15 35 66
  6.  
  7. 1 6 11 19 21 39 55 100

MySQL中常见索引有:

  • 普通索引
  • 唯一索引
  • 主键索引
  • 组合索引

1、普通索引

普通索引仅有一个功能:加速查询

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. index ix_name (name)
  7. )

创建表和索引

  1. create index index_name on table_name(column_name)

创建索引

  1. drop index_name on table_name;

删除索引

  1. show index from table_name;

查看索引

注意:对于创建索引时如果是BLOB 和 TEXT 类型,必须指定length。

  1. create index ix_extra on in1(extra(32));

2、唯一索引

唯一索引有两个功能:加速查询 和 唯一约束(可含null)

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. unique ix_name (name)

表+唯一索引

  1. create unique index 索引名 on 表名(列名)

创建唯一索引

  1. drop unique index 索引名 on 表名

删除唯一索引

3、主键索引

主键有两个功能:加速查询 和 唯一约束(不可含null)

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. index ix_name (name)
  7. )
  8.  
  9. OR
  10.  
  11. create table in1(
  12. nid int not null auto_increment,
  13. name varchar(32) not null,
  14. email varchar(64) not null,
  15. extra text,
  16. primary key(ni1),
  17. index ix_name (name)
  18. )

创建主键和主键索引

  1. alter table 表名 add primary key(列名);

创建主键

  1. alter table 表名 drop primary key;
  2. alter table 表名 modify 列名 int, drop primary key;

删除主键

4、组合索引

组合索引是将n个列组合成一个索引

其应用场景为:频繁的同时使用n列来进行查询,如:where n1 = 'alex' and n2 = 666。

  1. create table in3(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text
  6. )

创建表

  1. create index ix_name_email on in3(name,email);

创建组合索引

如上创建组合索引之后,查询:

  • name and email  -- 使用索引
  • name                 -- 使用索引
  • email                 -- 不使用索引

注意:对于同时搜索n个条件时,组合索引的性能好于多个单一索引合并。

5、索引的相关命令和注意事项

  1. # 查看索引
  2. show index from 表名
  3.  
  4. # 查看执行时间
  5. set profiling = 1; # 开启profiling
  6. SQL... # 执行SQL语句
  7. show profiles; # 查看结果
  8.  
  9. # 避免使用select *
  10. # count(1)或count(列) 代替 count(*)
  11. # 创建表时尽量时 char 代替 varchar
  12. # 表的字段顺序固定长度的字段优先
  13. # 组合索引代替多个单列索引(经常使用多个条件查询时)
  14. # 尽量使用短索引
  15. # 使用连接(JOIN)来代替子查询(Sub-Queries)
  16. # 连表时注意条件类型需一致
  17. # 索引散列值(重复少)不适合建索引,例:性别不适合

6、正确使用索引

  1. # like '%xx',避免%_写在开头
  2. select * from tb1 where name like '%n';
  3.  
  4. # 使用函数
  5. select * from tb1 where reverse(name) = 'nick';
  6.  
  7. # or
  8. select * from tb1 where nid = 1 or email = '630571017@qq.com';
  9. 注:当or条件中有未建立索引的列才失效,否则会走索引
  10.  
  11. # 类型不一致
  12. 如果列是字符串类型,传入条件是必须用引号引起来。
  13. select * from tb1 where name = 999;
  14.  
  15. # !=,不等于
  16. select * from tb1 where name != 'nick'
  17. 注:如果是主键,则还是会走索引
  18. select * from tb1 where nid != 123
  19.  
  20. # >,大于
  21. select * from tb1 where name > 'nick'
  22. 注:如果是主键或索引是整数类型,则还是会走索引
  23. select * from tb1 where nid > 123
  24. select * from tb1 where num > 123
  25.  
  26. # order by
  27. select email from tb1 order by name desc;
  28. 当根据索引排序时候,选择的映射如果不是索引,则不走索引
  29. 注:如果对主键排序,则还是走索引:
  30. select * from tb1 order by nid desc;
  31.  
  32. # 组合索引最左前缀
  33. 如果组合索引为:(name,email),查询使用:
  34. name and email -- 使用索引
  35. name -- 使用索引
  36. email -- 不使用索引

六、其他

  1. delimiter \\
  2. CREATE PROCEDURE proc_if ()
  3. BEGIN
  4.  
  5. declare i int default 0;
  6. if i = 1 THEN
  7. SELECT 1;
  8. ELSEIF i = 2 THEN
  9. SELECT 2;
  10. ELSE
  11. SELECT 7;
  12. END IF;
  13.  
  14. END\\
  15. delimiter ;

if语句

  1. delimiter \\
  2. CREATE PROCEDURE proc_while ()
  3. BEGIN
  4.  
  5. DECLARE num INT ;
  6. SET num = 0 ;
  7. WHILE num < 10 DO
  8. SELECT
  9. num ;
  10. SET num = num + 1 ;
  11. END WHILE ;
  12.  
  13. END\\
  14. delimiter ;

while循环

  1. delimiter \\
  2. CREATE PROCEDURE proc_repeat ()
  3. BEGIN
  4.  
  5. DECLARE i INT ;
  6. SET i = 0 ;
  7. repeat
  8. select i;
  9. set i = i + 1;
  10. until i >= 5
  11. end repeat;
  12.  
  13. END\\
  14. delimiter ;

repeat循环

  1. delimiter \\
  2. CREATE PROCEDURE proc_loop ()
  3. BEGIN
  4.  
  5. declare i int default 0;
  6. loop_label: loop
  7. select i;
  8. set i=i+1;
  9. if i>=5 then
  10. leave loop_label;
  11. end if;
  12. end loop;
  13.  
  14. END\\
  15. delimiter ;

loop

  1. delimiter \\
  2. DROP PROCEDURE IF EXISTS proc_sql \\
  3. CREATE PROCEDURE proc_sql ()
  4. BEGIN
  5. declare p1 int;
  6. set p1 = 11;
  7. set @p1 = p1;
  8.  
  9. PREPARE prod FROM 'select * from tb2 where nid > ?';
  10. EXECUTE prod USING @p1;
  11. DEALLOCATE prepare prod;
  12.  
  13. END\\
  14. delimiter ;

动态执行mysql

 七、执行计划

  1. mysql> explain select * from suoning;
  2. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  4. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  5. | 1 | SIMPLE | suoning | ALL | NULL | NULL | NULL | NULL | 4 | |
  6. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  7. 1 row in set (1.67 sec)
  8.  
  9. id
  10. 查询顺序标识
  11. 如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
  12. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  13. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  14. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  15. | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 9 | NULL |
  16. | 2 | DERIVED | tb1 | range | PRIMARY | PRIMARY | 8 | NULL | 9 | Using where |
  17. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  18. 特别的:如果使用union连接气值可能为null
  19.  
  20. select_type
  21. 查询类型
  22. SIMPLE 简单查询
  23. PRIMARY 最外层查询
  24. SUBQUERY 映射为子查询
  25. DERIVED 子查询
  26. UNION 联合
  27. UNION RESULT 使用联合的结果
  28. ...
  29. table
  30. 正在访问的表名
  31.  
  32. type
  33. 查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
  34. ALL 全表扫描,对于数据表从头到尾找一遍
  35. select * from tb1;
  36. 特别的:如果有limit限制,则找到之后就不在继续向下扫描
  37. select * from tb1 where email = 'seven@live.com'
  38. select * from tb1 where email = 'seven@live.com' limit 1;
  39. 虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
  40.  
  41. INDEX 全索引扫描,对索引从头到尾找一遍
  42. select nid from tb1;
  43.  
  44. RANGE 对索引列进行范围查找
  45. select * from tb1 where name < 'alex';
  46. PS:
  47. between and
  48. in
  49. > >= < <= 操作
  50. 注意:!= > 符号
  51.  
  52. INDEX_MERGE 合并索引,使用多个单列索引搜索
  53. select * from tb1 where name = 'alex' or nid in (11,22,33);
  54.  
  55. REF 根据索引查找一个或多个值
  56. select * from tb1 where name = 'seven';
  57.  
  58. EQ_REF 连接时使用primary key unique类型
  59. select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
  60.  
  61. CONST 常量
  62. 表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
  63. select nid from tb1 where nid = 2 ;
  64.  
  65. SYSTEM 系统
  66. 表仅有一行(=系统表)。这是const联接类型的一个特例。
  67. select * from (select nid from tb1 where nid = 1) as A;
  68. possible_keys
  69. 可能使用的索引
  70.  
  71. key
  72. 真实使用的
  73.  
  74. key_len
  75. MySQL中使用索引字节长度
  76.  
  77. rows
  78. mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
  79.  
  80. extra
  81. 该列包含MySQL解决查询的详细信息
  82. Using index
  83. 此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
  84. Using where
  85. 这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
  86. Using temporary
  87. 这意味着mysql在对查询结果排序时会使用一个临时表。
  88. Using filesort
  89. 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
  90. Range checked for each record(index map: N)”
  91. 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。

MYSQL进阶,新手变司机的更多相关文章

  1. 【转】MySQL— 进阶

    [转]MySQL— 进阶 目录 一.视图 二.触发器 三.函数 四.存储过程 五.事务 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需 ...

  2. MySQL进阶篇(03):合理的使用索引结构和查询

    本文源码:GitHub·点这里 || GitEE·点这里 一.高性能索引 1.查询性能问题 在MySQL使用的过程中,所谓的性能问题,在大部分的场景下都是指查询的性能,导致查询缓慢的根本原因是数据量的 ...

  3. (6)MySQL进阶篇SQL优化(MyISAM表锁)

    1.MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源 (如 CPU.RAM.I/O 等)的抢占以外,数据也是一种供许多用户共享的资源.如何保证数 据并 ...

  4. mysql进阶(二十九)常用函数

    mysql进阶(二十九)常用函数 一.数学函数 ABS(x) 返回x的绝对值 BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制) CEILING(x) 返回大于x的最小整数值 EXP ...

  5. mysql进阶(二十八)MySQL GRANT REVOKE用法

    mysql进阶(二十八)MySQL GRANT REVOKE用法   MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...

  6. mysql进阶(二十七)数据库索引原理

    mysql进阶(二十七)数据库索引原理 前言   本文主要是阐述MySQL索引机制,主要是说明存储引擎Innodb.   第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础.    ...

  7. mysql进阶(二十六)MySQL 索引类型(初学者必看)

    mysql进阶(二十六)MySQL 索引类型(初学者必看)   索引是快速搜索的关键.MySQL 索引的建立对于 MySQL 的高效运行是很重要的.下面介绍几种常见的 MySQL 索引类型.   在数 ...

  8. mysql进阶(十六)常见问题汇总

    mysql进阶(十六)常见问题汇总 MySQL视图学习: http://www.itokit.com/2011/0908/67848.html 执行删除操作时,出现如下错误提示: 出现以上问题的原因是 ...

  9. MySQL进阶(视图)---py全栈

    目录 mysql进阶(视图)---py全栈 一.什么是视图? 二.视图的特性 三.视图的优点 四.使用场合 五.视图基本操作 六.案例 mysql进阶(视图)---py全栈 一.什么是视图? 视图是从 ...

随机推荐

  1. MongoDB 创建 Database 和 Collection

    在开始使用MongoDB(Version:3.2.9)之前,必须首先在MongoDB中创建 Database 和 Collection.Database是相互独立的,每个Database都有自己的Co ...

  2. distribution 中一直在运行 waitfor delay @strdelaytime 语句

    Replication 自动创建来一个 Job:Replication monitoring refresher for distribution,这个Agent执行一个sp: dbo.sp_repl ...

  3. Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)

    0.检查配置 1. VMWare上运行的Ubuntu,并不能支持真实的GPU(除了特定版本的VMWare和特定的GPU,要求条件严格,所以我在VMWare上搭建好了Caffe环境后,又重新在Windo ...

  4. ASP.NET MVC之如何看待内置配置来提高性能优化(四)

    前言 前几篇我们比较基础的讲了下MVC中的知识,这一节我们穿插点知识,讲讲MVC中我们可以提高性能的办法. Razor视图引擎优化(优化一) 我们知道默认情况下配置MVC去解析一个视图会首先约定通过查 ...

  5. 应用程序框架实战十四:DDD分层架构之领域实体(基础篇)

    上一篇,我介绍了自己在DDD分层架构方面的一些感想,本文开始介绍领域层的实体,代码主要参考自<领域驱动设计C#2008实现>,另外参考了网上找到的一些示例代码. 什么是实体 由标识来区分的 ...

  6. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

  7. C# 在word中查找及替换文本

    C# 在word中查找及替换文本 在处理word文档时,很多人都会用到查找和替换功能.尤其是在处理庞大的word文档的时候,Microsoft word的查找替换功能就变得尤为重要,它不仅能让我们轻易 ...

  8. Word基础

    1.页面设置 默认大小A4,长宽比0.618 页面布局 2.字体设置 选择要设置的字体->右键->字体 3.选择性粘贴 4.段落设置 选择文字->右键->段落 5.表格 =SU ...

  9. MySQL学习(二)SQL语句的总结

    1.连接查询和关联查询连接查询:把两个表中相同的元素的连接就可以查询,使用:where里,select table1.*,table2.* from table1,table2 where table ...

  10. 优化JS加载时间过长的一种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 去年公司在漳州的一个项目中,现场工程人员反映地图部分出图有点 ...