对触发器的支持是在MySQL 5中增加的。MySQL语句在需要时被执行,存储过程也是如此。但是,如果你想要某条语句(或某些语句)在事件发生时自动执行,怎么办呢?每当增加一个顾客到某个数据库表时,都检查其电话号码格式是
否正确,州的缩写是否为大写;
每当订购一个产品时,都从库存数量中减去订购的数量;
无论何时删除一行,都在某个存档表中保留一个副本
所有这些例子的共同之处是它们都需要在某个表发生更改时自动处理。这确切地说就是触发器。触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于 BEGIN 和 END 语句之间的一组语句):1.DELETE 2.INSERT 3.UPDATE 其他MySQL语句不支持触发器。
创建触发器时,需要给出4个信息:唯一的触发器名;
触发器关联的表;
触发器应该响应的活动(DELETE,INSERT或UPDATE)
触发器何时执行(处理之前或之后)
保持每个数据库的触发器名唯一:MySQL5中,触发器名必须在每个表里唯一。
触发器使用CREATE TRIGGER语句创建。(trigger 翻译为 触发;使运行)
1
2
3
4
5CREATE TRIGGER newproduct AFTER INSERT ON products
FOR EACH ROW SELECT 'Product added';
-- 会报错 在mysql的trigger和function中不能出现select * from table形式的查询,因为其会返回一个结果集;
-- [Err] 1415 - Not allowed to return a result set from a trigger
-- 以使用用户变量在function中,然后在外部使用select @用户变量查看你的变量值
CREATE TRIGGER 用来创建名为 newproduct 的新触发器。触发器可在一个操作发生之前或之后执行,这里给出了 AFTER INSERT ,所以此触发器将在 INSERT 语句成功执行后执行。这个触发器还指定 FOREACH ROW ,因此代码对每个插入行执行。
DELETE触发器:在DELETE触发器代码内,可以引用一个名为OLD的虚拟表,访问被删除的行。OLD的值全部只读,不能更新
1
2
3
4
5
6
7-- 演示使用 OLD 保存将要被删除的行到一个存档表中
CREATE TRIGGER deleteorder BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
INSERT INTO archive_orders(order_num, order_date, cust_id)
VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
END;
UPDATE触发器:在UPDATE触发器代码时,可以引用一个名为OLD的虚拟表访问以前的值,引用一个名为NEW的虚拟表访问新更新的值。
在BEFORE UPDATE触发器中,NEW中的值可能也被更新。
OLD中的值全都是只读的,不能更新。1
2
3-- 保证州名是大写
CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW SET NEW.vend_state = Upper(NEW.vend_state);
每次更新一行时,NEW.vend_state中的值都用Upper(NEW.vend_state)替换。
总结创建触发器可能需要特殊的安全访问权限,但是触发器的执行不需要。
应该用触发器来保证数据的一致性。
MYSQL触发器不支持CALL语句。
学习了什么是触发器,如何创建,如何使用它。
管理事务处理
MyISAM不支持事务管理,InnoDB支持事务管理。 事务处理可以用来维护数据库的完整性(原子性),它保证成批的MySQL操作要么完全执行,要么完全不执行。
事务(transaction):指一组SQL语句。
回退(rollback):指撤销执行SQL语句的过程。
提交(commit):指将未存储的SQL语句结果写入数据库表。
保留点(savepoint):指事务处理中设置的临时占位符,你可以对它发布回退。
控制事务处理
MySQL使用下面的语句来标识事务的开始:START TRANSACTION
使用ROLLBACK
MySQL的ROLLBACK命令用来撤销MySQL语句
1
2
3
4
5
6SELECT * FROM odertotals;
START TRANSACTION;
DELETE FROM ordertotals;
SELECT * FROM ordertotals;
ROLLBACK;
SELECT * FROM ordertotals;
ROLLBACK只能在一个事务处理内使用(在执行一条START TRANSACTION命令后)。
哪些语句可以回退?
事务处理用来管理INSERT、UPDATE和DELETE语句,不能回退SELECT语句。也不能回退CREATE或DROP操作。事务处理块中可以使用这两天语句,但如果执行回退,他们不会被撤销。
使用COMMIT
一般的MySQL语句都是直接针对数据库表执行和编写的,提交操作是自动进行的。
但是,在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句。
1
2
3
4START TRANSACTION;
DELETE FROM orderitems WHERE order_num = 20010;
DELETE FROM orders WHERE order_num = 20010;
COMMIT;
如果第一条DELETE起作用,但第二条失败,则DELETE不会提交(实际上,它是被自动撤销的)
隐含事务关闭: 当COMMIT或ROLLBACK语句执行后,事务会自动关闭(将来的更改会隐含提交)。
使用保留点
简单的ROLLBACK和COMMIT语句就可以写入或撤销整个事务处理。但是,只是对简单的事务处理才能这样做,更复杂的事务处理可能需要部分提交或回退。
为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。如果需要回退,可以回退到某个占位符。
占位符称为保留点,为了创建占位符,可以使用SAVEPOINT语句:
1SAVEPOINT delete1;
每个保留点都取标识它的唯一名字,以便在回退时,MySQL知道要回退到何处,为了回退到保留点,可进行:ROLLBACK TO delete1;
保留点在事务完成后释放。
更改默认的提交行为
默认的MySQL行为是自动提交所有更改,为指示MySQL不自动提交更改,需要使用以下语句:
1SET autocommit=0;
autocommit标志决定是否自动提交更改,不管有没有COMMIT语句。设置autocommit为0(假)指示MySQL不自动提交更改(直到autocommit被设置为真为止)。
标志为连接专用: autocommit标志是针对 每个连接 2而不是服务器的。
全球化和本地化
字符集和校对顺序
数据库表被用来存储和检索数据。不同的语言和字符集需要以不同的方式存储和检索。因此,MySQL需要适应不同的字符集(不同的字母和字符),适应不同的排序和检索数据的方法。
字符集: 为字母和符号的集合。
编码: 为某个字符集成员的内部表示。
校对: 为规定字符如何比较的命令。
使用字符集和校对顺序1SHOW CHARACTER SET;
显示所有可用的字符集以及每个字符集的描述和默认校对。
1SHOW COLLATION;
显示所有的校对,以及他们适用的字符集。
例如, latin1 对不同的欧洲
语言有几种校对,而且许多校对出现两次,一次区分大小写(由 _cs 表示),一次不区分大小写(由 _ci 表示)。
为了确定所用的字符集和校对,可使用以下语句:
1
2SHOW VARIABLES LIKE `character%`;
SHOW VARIABLES LIKE `collation%`;
改善性能MySQL是用一系列的默认设置预先配置的,从这些设置开始通常是很好的,但过一段时间后你可能需要调整内存分配、缓冲区大小等。
MySQL一个多用户多线程的DBMS,它经常同时执行多个任务。如果这些任务中的某个执行缓慢,则所有请求都会执行缓慢。如果性能不良,可使用SHOW PROCESSLIST显示所有活动进程。
使用EXPLAIN语句让MySQL解释它将如何执行一条SELECT语句。
使用正确的数据类型。
绝不要检索比需求还要多的数据。不要使用SELECT *
在导入数据时,应该关闭自动提交。
索引数据库表以改善数据检索性能。
SELECT语句有一系列复杂的OR条件,可以使用多条SELECT语句和连接他们的UNION语句,可极大改善性能。