触发器
触发器是由MySQL基本命令事件触发某种特定操作。
创建触发器
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE
删除触发器:
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
简单例子:
创建一个触发器,对于表timelog,每一次向animals插入记录,time字段自动被写入。
创建表:
mysql> create table timelog( id smallint primary key, time varchar(50) not null);
创建触发器:
mysql> create trigger auto_save_time after insert on animals for each row insert into timelog(time) values (now());
向animals插入数据使得触发器工作
mysql> insert into animals values("20130019","tiger");
Query OK, 1 row affected (0.00 sec)
mysql> select * from timelog;
+----+---------------------+
| id | time |
+----+---------------------+
| 0 | 2016-12-22 16:01:57 |
+----+---------------------+
对于trigger_body
我们可以写成
begin
statements.
end
这样即可执行多条语句。
一张表在相同的触发时间只能有一个触发器。
查看触发器:
mysql> show triggers\G;
*************************** 1. row ***************************
Trigger: auto_save_time
Event: INSERT
Table: animals
Statement: insert into timelog(time) values (now())
Timing: AFTER
Created: NULL
sql_mode: NO_ENGINE_SUBSTITUTION
Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)
这是查看选择数据库的方法,假设触发器很多,那么,可以使用如下语句来实现具体的查阅:
mysql> show create trigger auto_save_time\G;
#或者:
mysql> select * from information_schema.triggers where trigger_name='auto_save_time'\G;
想要查看MySQL中所有的触发器,那么可以:
mysql> select * from
触发器中不能含有start transcation, commit, rollback, call
等关键字。
事务
事务是由一个或多个SQL语句构成,他是一个整体,一旦中间发生任何的错误,事务将会回滚。
ACID测试要求每一个事务必须满足这样4个特性:原子性(不可分割),一致性(MySQL日志机制处理,记录数据库所有的变化),孤立性(保证事务与事务不会发生冲突),持久性(即便是数据库崩溃,仍能通过备份和日志恢复丢失的数据)。
MySQL支持事务的数据表类型是innoDB、BDB。
事务的创建:
START TRANSACTION
[transaction_characteristic [, transaction_characteristic] ...]
transaction_characteristic:
WITH CONSISTENT SNAPSHOT
| READ WRITE
| READ ONLY
BEGIN [WORK]
事务提交:COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
事务回滚:ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
例子:
root创建事务:
mysql> start transaction;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test values(8,"hello",20);
Query OK, 1 row affected (0.00 sec)
普通用户查看test表,没能发现id=8的记录。
mysql> select * from test;
+----+------+-------+
| id | name | price |
+----+------+-------+
| 7 | dada | NULL |
| 6 | dada | 0 |
| 1 | tag1 | 12 |
| 2 | tag2 | 13 |
| 3 | tag3 | 14 |
| 4 | tag4 | 10 |
| 5 | tag6 | 16 |
+----+------+-------+
当root提交事务commit
后,普通用户才能发现test表发生改变。
mysql> select * from test;
+----+-------+-------+
| id | name | price |
+----+-------+-------+
| 7 | dada | NULL |
| 6 | dada | 0 |
| 8 | hello | 20 |
| 1 | tag1 | 12 |
| 2 | tag2 | 13 |
| 3 | tag3 | 14 |
| 4 | tag4 | 10 |
| 5 | tag6 | 16 |
+----+-------+-------+
事务一旦成功执行并commit后,rollback是没有意义的。
如果在一个事务中又打开一个事务,那么前一个事务时会被自动提交的。
设置自动回滚操作:set AUTOCOMMIT=0(or 1)
查看autocommit变量:
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
查看事务的孤立性:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
设置事务的孤立性:
SET [GLOBAL | SESSION] TRANSACTION
transaction_characteristic [, transaction_characteristic] ...
transaction_characteristic:
ISOLATION LEVEL level
| READ WRITE
| READ ONLY
level:
REPEATABLE READ
| READ COMMITTED
| READ
例如:set global transaction isolation level read committed;
事务的孤立级越高,性能越低,但安全性也越高。
表的锁定和解锁:
LOCK TABLES
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] ...
read锁:其他用户只能进行都操作(比如select),不能进行写操作(比如insert,一直阻塞,直到解除锁定)。自己进行写操作则会出现错误信息,比如ERROR 1099 (HY000): Table 'test' was locked with a READ lock and can't be updated
write锁:上锁者可读可写,其他用户不能读、写(阻塞,直到解锁,操作才能进行)
正则查询
正则表达式中的模式匹配字符
模式字符 | 含义 |
^ | 以特定字符(串)开头 |
$ | 以特定字符(串)结尾 |
. | 匹配任意字符,包括回车换行 |
[characterset] | 匹配字符集合中任意一个字符 |
[^字符集合] | 匹配除了字符集合中字符的任意一个字符 |
s1|s2|s3 | 匹配s1,s2,s3字符串的任意一个字符串 |
* | 匹配x个*前的字符,其中x>=0 |
+ | 匹配x个*前的字符,其中x>0 |
string{N} | 匹配字符串出现N次 |
string{M,N} | 匹配字符串出现至少出现M次,至多N次 |
使用正则表达式查询
语法:
字段名 REGEXP 'regular expression'
原表:
mysql> select * from students;
+----------+---------+
| sno | sname |
+----------+---------+
| 20130001 | stephen |
| 20130002 | Elena |
| 20130003 | Demon |
+----------+---------+
例子:
1 . 查询students中以2013的sno开头的记录。
mysql> select * from students where sno REGEXP '^2013';
+----------+---------+
| sno | sname |
+----------+---------+
| 20130001 | stephen |
| 20130002 | Elena |
| 20130003 | Demon |
+----------+---------+
2 . 将20130001或者20130002的sno记录从students找出来。
mysql> select * from students where sno REGEXP '20130001|20130002';
+----------+---------+
| sno | sname |
+----------+---------+
| 20130001 | stephen |
| 20130002 | Elena |
+----------+---------+
3 . 找出以E开头的sname的student记录
mysql默认情况下是不区分大小的,我们给sname增加binary属性。
格式:modify column col_name new_format
mysql> alter table students modify column sname varchar(30) binary;
Query OK, 3 rows affected (0.10 sec)
Records: 3 Duplicates: 0 Warnings: 0
正则表示查询:
mysql> select * from students where sname REGEXP '[E]';
+----------+-------+
| sno | sname |
+----------+-------+
| 20130002 | Elena |
+----------+-------+
4 . 查询连续出现2次e的sname的记录。
mysql> select * from students where sname REGEXP 'e{2}';
Empty set (0.00 sec)