SQL 简介
基本简介
SQL (Structured Query Language:结构化查询语言) 是用于管理关系数据库管理系统(RDBMS)的一门语言。
SQL 的范围包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制。
一些最重要的 SQL 命令
SELECT - 从数据库中提取数据
UPDATE - 更新数据库中的数据
DELETE - 从数据库中删除数据
INSERT INTO - 向数据库中插入新数据
CREATE DATABASE - 创建新数据库
ALTER DATABASE - 修改数据库
CREATE TABLE - 创建新表
ALTER TABLE - 变更(改变)数据库表
DROP TABLE - 删除表
CREATE INDEX - 创建索引(搜索键)
DROP INDEX - 删除索引
SQL 标准
演变历史
SQL 标准简要的发展与演化历史:
- 1986 年,ANSI X3.135-1986,ISO/IEC 9075:1986,SQL-86。这是 ANSI 首次将 SQL 语言标准化的版本。
- 1989 年,ANSI X3.135-1989,ISO/IEC 9075:1989,SQL-89。增加了完整性约束。
- 1992 年,ANSI X3.135-1992,ISO/IEC 9075:1992,SQL-92(SQL2)。最重要的一个版本。 引入了标准的分级概念。
- 1999 年,ISO/IEC 9075:1999,SQL:1999(SQL3)。变动最大的一个版本。改变了标准符合程度的定义;增加了面向对象特性、正则表达式、存储过程、Java 等支持。
- 2003 年,ISO/IEC 9075:2003,SQL:2003。引入了 XML、Window 函数等。
- 2008 年,ISO/IEC 9075:2008,SQL:2008。引入了 TRUNCATE 等。
- 2011 年,ISO/IEC 9075:2011,SQL:2011。引入了时序数据等。
- 2016 年,ISO/IEC 9075:2016,SQL:2016。引入了 JSON 等。
提及标准,大家容易想到的一个问题就是产品对标准的遵循程度,也就是标准的符合性到底如何,因为它会影响代码在不同系统之间迁移的难度。很遗憾的是,SQL 标准因为定义过于宽泛等技术和非技术原因,不同产品对标准的符合程度存在很大的差异。大到功能特性,小到语法语义的细节,在不同产品之间都存在很多差异,造成实际的应用迁移远比 C/C++ 程序的迁移要复杂很多。因此,尽管很多产品都号称自己符合 SQL 标准,并不意味着应用可以容易的在它们之间切换。除了 Oracle、DB2 等经典的商业产品,以及 PostgreSQL、MySQL 等开源产品总体上对 SQL 标准的符合程度较高以外,很多产品提到的 SQL 标准,涉及的内容其实是 SQL92 里头最基本或最核心的一部分(属于入门级的范畴。SQL92 本身是分级的,包括入门级、过渡级、中间级和完全级)。
SQL-86
SQL-92
SQL-99
基本语句
数据定义语言 DDL
创建库表 CREATE
创建数据库使用 CREATE DATABASE
,可以设定数据库字符集
CREATE DATABASE db_name CHARACTER SET utf8 ;
创建数据表使用 CREATE TABLE
CREATE TABLE table_name
(
column_name1 datatype limitinfo,
...
column_namen datatype limitinfo
);
修改表 ALTER
可以通过 ALTER
修改数据表列信息,支持新增列,删除列
ALTER TABLE table_name ADD column_name datatype ;
ALTER TABLE table_name DROP COLUMN column_name ;
MySQL,Oracle支持在一定条件下修改列属性,语法如下:
ALTER TABLE table_name MODIFY COLUMN column_name datatype
删除库表 DROP
通过使用 DROP 语句,可以轻松地删除索引、表和数据库。
DROP TABLE table_name;
DROP DATABASE db_name;
数据操纵语言 DML
数据插入 INSERT
INSERT
支持插入单行或多行的数据。
INSERT INTO table_name VALUES(value1,value2,...) ;
存储到表中每一列的数 据在 VALUES 子句中给出,必须给每一列提供一个值。如果某列没有值,则应该使用NULL值。
各列必须以它们在表定义中出现的次序填充
在 SQLite 中支持从一个表导出数据到另一个表
INSERT INTO target_table SELECT column_name FROM source_table ;
SELECT column_name INTO target_table FROM source_table ;
INSERT SELECT 与SELECT INTO 的一个重要差别是前者导出数据,而后者导入数据。
MySQL、Oracle、PostgreSQL 使用CREATE TABLE 语句实现从一个表复制到一个新表。
CREATE TABLE target_table AS SELECT * FROM source_table ;
数据更新 UPDATE
一般 UPDATE
语句可以通过 WHERE
语句限定更新范围,
UPDATE table_name
SET column1 = value1 , column2 = value2
WHERE condition ;
UPDATE语句中可以使用子查询,使得能用SELECT语句检索出的数据更新列数据。 SQL实现支持在UPDATE语句中使用FROM子句,用一个表的数据更新另一个表的行。
数据删除 DELETE
DELETE
支持限定条件的清除数据, TRUNCATE
一般用于清空整表数据
DELETE FROM table_name WHERE condition ;
TRUNCATE TABLE table_name ;
在 UPDATE或 DELETE语句使用 WHERE子句前,应该先用 SELECT进 行测试,保证它过滤的是正确的记录,以防编写的 WHERE子句不正确。
数据查询语言 DQL
基础查询
从多个联合表中查询对应符合要求的数据,包含连接、筛选、分组、分组筛选、排序等规则
SELECT column_name1,
FROM table_name1
JOIN table_name2
ON condition1
WHERE conditions
GROUP BY column_name
HAVING COUNT(1) >= 2
ORDER BY column_name DESC
分页查询
使用SELECT查询时,如果结果集数据量很大,比如几万行数据,放在一个页面显示的话数据量太大,不如分页显示,每次显示100条。
不同数据库支持的分页查询语法不一致
比如 MySQL ,PostgreSQL 的查询语法为:
SELECT column_name FROM table_name LIMIT N ;
SELECT column_name FROM table_name ORDER BY column_name ASC LIMIT N OFFSET M ;
LIMIT N OFFSET M
直白的可以理解为:跳过 M 条数据取前 N 条数据。
Oracle 中通过 ROWNUM
可以限制数据取数范围:
SELECT column_name FROM table_name WHERE ROWNUM <= N ;
SELECT column_name FROM table_name WHERE ROWNUM BETWEEN X AND Y;
数据控制语言 DCL
权限管理 GRANT REVOKE
SQL中使用 Grant 和 Revoke 语句向用户授予或收回对数据的操作权限, Grant 语句向用户授予权限,Revoke语句收回已经授予用户的权限。
WITH GRANT OPTION
有这个句段则用户还可以授权给别人
GRANT SELECT,UPDATE,DELETE ON TABLE table_name TO user_name ;
GRANT ALL PRIVILEGES ON TABLE table_name TO user_name WITH GRANT OPTION ;
授予用户的权限可以由数据库管理员或其他授权者用REVOKE语句收回;CASCADE表示级联收回,否则系统拒绝此操作
REVOKE SELECT,UPDATE,DELETE ON TABLE table_name FROM user_name CASCADE;
REVOKE UPDATE ON TABLE SC FROM PUBLIC ;
- 权限查询
在 MySQL 中,可以通过查看 mysql.user 表中的数据记录来查看相应的用户权限,也可以使用 SHOW GRANTS 语句查询用户的权限。
SELECT * FROM mysql.user;
SHOW GRANTS FOR 'username'@'hostname';
事务管理 COMMIT ROLLBACK
COMMIT 即提交事务。
ROLLBACK 就是与 COMMIT 相反,不提交事务,可以理解成撤回的意思。
查看事务是否提交,1或者ON表示自动提交;0或者OFF表示手动提交:需要 COMMIT 命令提交事务。
select @@autocommit;
show variables like ‘%autocommit%’;
其他关键字
去重 DISTINCT
DISTINCT 关键字需要和 SELECT 语句一起使用,用来删除结果集中所有重复的记录,仅保留唯一的一条记录。
SELECT DISTINCT column1, column2,.....columnN FROM table_name WHERE condition
结果集并 UNION
UNION 操作符合并两个或多个 SELECT 语句的结果。
UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
UNION ALL
则表示不需去除重复项的合并。
逻辑运算 AND OR NOT
逻辑运算 AND
、 OR
用于基于一个以上的条件对记录进行过滤。
逻辑运算 NOT
用于一个条件取否,长和 LIKE
, IN
等关键词搭配使用
通配 LIKE
通配符与 LIKE
操作符一起使用,常见的通配符有 %
, _
%
代表多个0个或多个字符
_
代表一个字符
-- 通配以 Google 开头的记录
SELECT * FROM table_name where column_name LIKE 'Google%'
当需要用复杂规则时,使用关键词 RLIKE
和 REGEXP
用来匹配正则表达式
SELECT * FROM table_name WHERE column_name REGEXP regexp_string ;
SELECT * FROM table_name WHERE column_name RLIKE regexp_string ;
常用函数
不同数据库在使用常见函数时会存在一定差异,以下如果没有特殊说明以 MySQL 为例介绍一些常用函数。
字符串函数
函数名称 | 作用 |
---|---|
LENGTH | 计算字符串长度函数,返回字符串的字节长度 |
CONCAT | 合并字符串函数,返回结果为连接参数产生的字符串,参数可以使一个或多个 |
INSERT | 替换字符串函数 |
LOWER | 将字符串中的字母转换为小写 |
UPPER | 将字符串中的字母转换为大写 |
LEFT | 从左侧字截取符串,返回字符串左边的若干个字符 |
RIGHT | 从右侧字截取符串,返回字符串右边的若干个字符 |
TRIM | 删除字符串左右两侧的空格 |
REPLACE | 字符串替换函数,返回替换后的新字符串 |
SUBSTRING | 截取字符串,返回从指定位置开始的指定长度的字符换 |
REVERSE | 字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串 |
数值函数
函数名称 | 作用 |
---|---|
ABS | 求绝对值 |
SQRT | 求二次方根 |
MOD | 求余数 |
CEIL 和 CEILING | 两个函数功能相同,都是返回不小于参数的最小整数,即向上取整 |
FLOOR | 向下取整,返回值转化为一个BIGINT |
RAND | 生成一个0~1之间的随机数,传入整数参数是,用来产生重复序列 |
ROUND | 对所传参数进行四舍五入 |
SIGN | 返回参数的符号 |
POW 和 POWER | 两个函数的功能相同,都是所传参数的次方的结果值 |
SIN | 求正弦值 |
ASIN | 求反正弦值,与函数 SIN 互为反函数 |
COS | 求余弦值 |
ACOS | 求反余弦值,与函数 COS 互为反函数 |
TAN | 求正切值 |
ATAN | 求反正切值,与函数 TAN 互为反函数 |
COT | 求余切值 |
时间日期函数
函数名称 | 作用 |
---|---|
CURDATE 和 CURRENT_DATE | 两个函数作用相同,返回当前系统的日期值 |
CURTIME 和 CURRENT_TIME | 两个函数作用相同,返回当前系统的时间值 |
NOW 和 SYSDATE | 两个函数作用相同,返回当前系统的日期和时间值 |
UNIX_TIMESTAMP | 获取 UNIX 时间戳函数,返回一个以 UNIX 时间戳为基础的无符号整数 |
FROM_UNIXTIME | 将 UNIX 时间戳转换为时间格式,与UNIX_TIMESTAMP互为反函数 |
MONTH | 获取指定日期中的月份 |
MONTHNAME | 获取指定日期中的月份英文名称 |
DAYNAME | 获取指定曰期对应的星期几的英文名称 |
DAYOFWEEK | 获取指定日期对应的一周的索引位置值 |
WEEK | 获取指定日期是一年中的第几周,返回值的范围是否为 0〜52 或 1〜53 |
DAYOFYEAR | 获取指定曰期是一年中的第几天,返回值范围是1~366 |
DAYOFMONTH | 获取指定日期是一个月中是第几天,返回值范围是1~31 |
YEAR | 获取年份,返回值范围是 1970〜2069 |
TIME_TO_SEC | 将时间参数转换为秒数 |
SEC_TO_TIME | 将秒数转换为时间,与TIME_TO_SEC 互为反函数 |
DATE_ADD 和 ADDDATE | 两个函数功能相同,都是向日期添加指定的时间间隔 |
DATE_SUB 和 SUBDATE | 两个函数功能相同,都是向日期减去指定的时间间隔 |
ADDTIME | 时间加法运算,在原始时间上添加指定的时间 |
SUBTIME | 时间减法运算,在原始时间上减去指定的时间 |
DATEDIFF | 获取两个日期之间间隔,返回参数 1 减去参数 2 的值 |
DATE_FORMAT | 格式化指定的日期,根据参数返回指定格式的值 |
WEEKDAY | 获取指定日期在一周内的对应的工作日索引 |
聚合函数
聚集函数(aggregate function) 对某些行运行的函数,计算并返回一个值
AVG(): 返回某列的平均值
COUNT(): 返回某列的行数
MAX(): 返回某列的最大值
MIN(): 返回某列的最小值
SUM(): 返回某列值之和
注:聚集函数一般忽略列值为NULL的行
对所有行执行计算,聚集函数指定ALL参数或不指定参数(因为ALL是默认行为)。 当只包含不同的值,则指定DISTINCT参数
高级功能
视图
数据库视图是虚拟表或逻辑表,它被定义为具有连接的SQL SELECT查询语句。 因为数据库视图与数据库表类似,它由行和列组成,因此可以根据数据库表查询数据。
使用视图的优势和应用场景:
重用 SQL 语句。
简化复杂的 SQL 操作。在编写查询后,可以方便地重用它而不必知道其基本查询细节。
使用表的一部分而不是整个表。
保护数据。可以授予用户访问表的特定部分的权限,而不是整个表的访问权限。
更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
算法属性允许您控制MySQL在创建视图时使用的机制。MySQL提供了三种算法:MERGE
,TEMPTABLE
和UNDEFINED
。
使用MERGE算法,MySQL首先将输入查询与定义视图的SELECT语句组合成单个查询。 然后MySQL执行组合查询返回结果集。
使用TEMPTABLE算法,MySQL首先根据定义视图的SELECT语句创建一个临时表,然后针对该临时表执行输入查询。因为MySQL必须创建临时表来存储结果集并将数据从基表移动到临时表,所以TEMPTABLE算法的效率比MERGE算法效率低。 另外,使用TEMPTABLE算法的视图是不可更新的。
当您创建视图而不指定显式算法时,UNDEFINED是默认算法。 UNDEFINED算法使MySQL可以选择使用MERGE或TEMPTABLE算法。MySQL优先使用MERGE算法进行TEMPTABLE算法,因为MERGE算法效率更高。
视图的创建、查看删除命令如下:
CREATE VIEW view_name AS SELECT col_name FROM table_name WHERE condition ;
SHOW CREATE VIEW view_name;
DROP VIEW view_name ;
在数据库中,视图和表共享相同的命名空间,因此视图和表不能具有相同的名称。 另外,视图的名称必须遵循表的命名规则。
索引
简单介绍
SQL 索引(Index)用于提高数据表的查询速度。一个表可以创建多个索引,一个索引可以包含一个或者多个字段。
从本质上看,索引是根据表的一个或者多个字段生成的子表,该子表中的数据已经进行了排序。子表除了包含指定字段中的数据,还包含一个 rowid 列,用于存储当前记录在原始表中的位置。用户无法看到索引,它只是用来加快查询速度。
为了提高查询效率,便于后期维护,索引都是基于某种数据结构而创建的,比如 B+ 树、B- 树、位图等。
仅在被频繁检索的字段上创建索引。
针对大数据量的表创建索引,而不是针对只有少量数据的表创建索引。
通常来说,经常查询的记录数目少于表中总记录数据的 15% 时,可以创建索引。这个比例并不绝对,它与全表扫描速度成反比。
尽量不要在有大量重复值得字段上建立索引,比如性别字段、季度字段等。
语法基础
创建、查看、删除索引
CREATE INDEX index_name
ON table_name ( column1, column2.....);
SHOW INDEX FROM table_name;
ALTER TABLE table_name DROP INDEX index_name;
不同类型的索引的语法
-- 建表时,主键默认为PRIMARY索引
-- 创建单列索引
CREATE INDEX single_index ON table_name(col_name);
-- 创建唯一索引
CREATE UNIQUE INDEX unique_index ON table_name(col_name);
-- 创建复合索引
CREATE INDEX multi_index ON table_name(col_name1,col_name2);
注意要点
满足复合索引的查询的两大原则:
最左前缀原则
MySQL 引擎在执行查询时,为了更好地利用索引,在查询过程中会动态调整查询字段的顺序
MySQL索引使用的数据结构主要有BTree
索引和hash
索引。
对于hash索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景建议选择BTree索引。
触发器
SQL 触发器是存储在数据库目录中的一组SQL语句。每当与表相关联的事件发生时,即会执行或触发SQL触发器,例如插入,更新或删除。
SQL 触发器是一种特殊类型的存储过程。触发器和存储过程之间的主要区别在于,当对表执行数据修改事件时,会自动调用触发器,而存储过程必须要明确地调用。
优缺点对比
-
优点
提供勒检查数据完整性的替代方法
可以捕获数据库层中业务逻辑中的错误
提供了运行计划任务的另一种方法:不必等待运行计划的任务,
审核表中数据的更改非常有用
-
缺点
只能提供扩展验证,并且无法替换所有验证
从客户端应用程序调用和执行SQL触发器不可见
可能会增加数据库服务器的开销
MySQL触发器类型
MySQL 的六类触发器
BEFORE INSERT - 在数据插入表之前被激活触发器。
AFTER INSERT - 在将数据插入表之后激活触发器。
BEFORE UPDATE - 在表中的数据更新之前激活触发器。
AFTER UPDATE - 在表中的数据更新之后激活触发器。
BEFORE DELETE - 在从表中删除数据之前激活触发器。
AFTER DELETE - 从表中删除数据之后激活触发器。
当使用不涉及INSERT,DELETE或UPDATE语句更改表中数据的语句时,不会调用与表关联的触发器。 例如,TRUNCATE
语句删除表的所有数据,但不调用与该表相关联的触发器。
有些语句使用了后台的INSERT语句,如REPLACE
语句或LOAD DATA
语句。如果使用这些语句,则调用与表关联的相应触发器。
触发器语法
CREATE TRIGGER trigger_name trigger_time trigger_event
ON table_name
FOR EACH ROW
BEGIN
...
END;
将触发器名称放在CREATE TRIGGER语句之后。触发器名称应遵循命名约定[trigger time][table name]/[trigger event],例如before_employees_update。
触发激活时间可以在之前或之后。必须指定定义触发器的激活时间。如果要在更改之前处理操作,则使用BEFORE关键字,如果在更改后需要处理操作,则使用AFTER关键字。
触发事件可以是INSERT,UPDATE或DELETE。此事件导致触发器被调用。 触发器只能由一个事件调用。要定义由多个事件调用的触发器,必须定义多个触发器,每个事件一个触发器。
触发器必须与特定表关联。没有表触发器将不存在,所以必须在ON关键字之后指定表名。
将SQL语句放在BEGIN和END块之间。这是定义触发器逻辑的位置。
DELIMITER $$
CREATE TRIGGER before_employee_update
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit
SET action = 'update',
employeeNumber = OLD.employeeNumber,
lastname = OLD.lastname,
changedat = NOW();
END$$
DELIMITER ;
在触发器的主体中,使用OLD关键字来访问受触发器影响的行的employeeNumber和lastname列。
在为INSERT定义的触发器中,可以仅使用NEW关键字。不能使用OLD关键字。
但是,在为DELETE定义的触发器中,没有新行,只能使用OLD关键字。
在UPDATE触发器中,OLD是指更新前的行,而NEW是更新后的行。
要查看当前数据库中的所有触发器,请使用SHOW TRIGGERS语句,如下所示:
SHOW TRIGGERS;
多触发器实现
如果表中有相同事件有多个触发器,MySQL将按照创建的顺序调用触发器。要更改触发器的顺序,需要在FOR EACH ROW
子句之后指定FOLLOWS
或PRECEDES
。如下说明 -
FOLLOWS
选项允许新触发器在现有触发器之后激活。
PRECEDES
选项允许新触发器在现有触发器之前激活。
存储过程
存储过程是存储在数据库目录中的一段声明性SQL语句。
优缺点分析
-
优点
通常存储过程有助于提高应用程序的性能。当创建,存储过程被编译之后,就存储在数据库中。
存储的程序对任何应用程序都是可重用的和透明的。 存储过程将数据库接口暴露给所有应用程序,以便开发人员不必开发存储过程中已支持的功能。
存储的程序是安全的。 数据库管理员可以向访问数据库中存储过程的应用程序授予适当的权限,而不向基础数据库表提供任何权限。
-
缺点
如果使用大量存储过程,那么使用这些存储过程的每个连接的内存使用量将会大大增加。 此外,如果您在存储过程中过度使用大量逻辑操作,则CPU使用率也会增加,因为数据库服务器的设计不当于逻辑运算。
存储过程的构造使得开发具有复杂业务逻辑的存储过程变得更加困难。
很难调试存储过程。只有少数数据库管理系统允许您调试存储过程。不幸的是,MySQL不提供调试存储过程的功能。
开发和维护存储过程并不容易。开发和维护存储过程通常需要一个不是所有应用程序开发人员拥有的专业技能。这可能会导致应用程序开发和维护阶段的问题。
语法规则
新建存储过程使用 CALL PROCEDURE
命令,调用存储过程使用 CALL
命令。
DELIMITER //
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END //
DELIMITER ;
CALL GetAllProducts();
要显示存储过程的字符,请使用 SHOW PROCEDURE STATUS
语句如下:
SHOW PROCEDURE STATUS [LIKE 'pattern' | WHERE expr];
显示特定存储过程的源代码,请使用SHOW CREATE PROCEDURE
语句如下:
SHOW CREATE PROCEDURE stored_procedure_name
使用游标
要处理存储过程中的结果集,请使用游标。游标允许您迭代查询返回的一组行,并相应地处理每行。
MySQL游标为只读,不可滚动和敏感。
只读:无法通过光标更新基础表中的数据。
不可滚动:只能按照SELECT语句确定的顺序获取行。不能以相反的顺序获取行。 此外,不能跳过行或跳转到结果集中的特定行。
敏感:有两种游标:敏感游标和不敏感游标。敏感游标指向实际数据,不敏感游标使用数据的临时副本。敏感游标比一个不敏感的游标执行得更快,因为它不需要临时拷贝数据。但是,对其他连接的数据所做的任何更改都将影响由敏感游标使用的数据,因此,如果不更新敏感游标所使用的数据,则更安全。
须使用DECLARE语句声明游标:
DECLARE cursor_name CURSOR FOR SELECT_statement;
游标声明必须在变量声明之后。如果在变量声明之前声明游标,MySQL将会发出一个错误。游标必须始终与SELECT语句相关联。
接下来,使用OPEN语句打开游标。OPEN语句初始化游标的结果集,因此您必须在从结果集中提取行之前调用OPEN语句。
OPEN cursor_name;
然后,使用FETCH语句来检索光标指向的下一行,并将光标移动到结果集中的下一行。
FETCH cursor_name INTO variables list;
之后,可以检查是否有任何行记录可用,然后再提取它。
最后,调用CLOSE语句来停用光标并释放与之关联的内存,如下所示:
CLOSE cursor_name;
当光标不再使用时,应该关闭它。
当使用MySQL游标时,还必须声明一个NOT FOUND处理程序来处理当游标找不到任何行时的情况。 因为每次调用FETCH语句时,游标会尝试读取结果集中的下一行。 当光标到达结果集的末尾时,它将无法获得数据,并且会产生一个条件。 处理程序用于处理这种情况。
要声明一个NOT FOUND处理程序,参考以下语法:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
finished是一个变量,指示光标到达结果集的结尾。请注意,处理程序声明必须出现在存储过程中的变量和游标声明之后。
计划任务事件
开启计划任务事件
MySQL事件是基于预定义的时间表运行的任务,因此有时它被称为预定事件。MySQL事件也被称为“时间触发”,因为它是由时间触发的,而不是像触发器一样更新表来触发的。MySQL事件类似于UNIX中的cron作业或Windows中的任务调度程序。
您可以在许多情况下使用MySQL事件,例如优化数据库表,清理日志,归档数据或在非高峰时间生成复杂的报告。
MySQL使用一个名为事件调度线程的特殊线程来执行所有调度的事件。可以通过执行以下命令来查看事件调度程序线程的状态。
SHOW PROCESSLIST;
-- 默认情况下,事件调度器是关闭的,需要通过以下命令开启
SET GLOBAL event_scheduler = ON;
-- 关闭事件调度器
SET GLOBAL event_scheduler = OFF;
事件调度器开启状态效果如下图:
EVENT 相关语法
-- 创建事件
CREATE EVENT [IF NOT EXIST] event_name
ON SCHEDULE schedule
DO
event_body
首先,在CREATE EVENT子句之后指定事件名称。事件名称在数据库模式中必须是唯一的。
其次,在ON SCHEDULE子句后面加上一个表。如果事件是一次性事件,则使用语法:AT timestamp [+ INTERVAL],如果事件是循环事件,则使用EVERY子句:EVERY interval STARTS timestamp [+INTERVAL] ENDS timestamp [+INTERVAL]
第三,将DO语句放在DO关键字之后。请注意,可以在事件主体内调用存储过程。 如果您有复合SQL语句,可以将它们放在BEGIN END块中。
-- 查看事件
SHOW EVENTS FROM db_name;
-- 删除事件
DROP EVENT [IF EXISTS] event_name;
-- 修改事件
ALTER EVENT event_name
ON SCHEDULE schedule
ON COMPLETION [NOT] PRESERVE
RENAME TO new_event_name
ENABLE | DISABLE
DO
event_body
参考材料
Introduction to SQL Standard(SQL标准简介)
标签:语句,触发器,name,基础,SQL,table,SELECT From: https://www.cnblogs.com/FangRyan/p/17187783.html