事务通常具有ACID四种特性:
- Atomic(原子性):所有语句是一个独立的逻辑单元,不可拆分。
- Consistent(一致性):数据库在事务执行前后必须是一致的(主要指各个表之间的关联性得以保证)
- Isolated(独立性):事务之间不应互相影响。因此事务无论是并发还是顺序执行的结果应该一样。
- Durable(持久性):事务执行成功的影响将永久的记录在数据库里。
默认情况下,MySQL的运行模式是自动提交,相当于每条语句都被隐式地当做了一个事务来执行。可以通过SET autocommit = 0
禁用自动提交模式。也可以通过调用START TRANSACTION
或BEGIN
语句来挂起自动提交模式,最后用COMMIT
语句结束事务从而让修改持久化。事务执行过程中如果出错,可以调用ROLLBACK
来撤销所有更改。
在禁用自动提交模式后,所有的语句都被视为事务的一部分,直到调用COMMIT
或ROLLBACK
为止。也可以通过重新激活自动提交模式来提交一个事务。
有一部分语句,包括用来创建、更改、或删除数据库或其中的对象的数据定义语言(DDL)语句,以及与锁定有关的语句都不能成为事务的一部分。如果在事务处理过程中调用了它们,那么服务器在执行这条语句之前将先提交当前事务。
如果事务未提交前意外中断了与服务器的连接,那么服务器胡自动回滚该客户端正提交的所有事务。
事务保存点
在事务开始后,可以设置SAVEPOINT,并在事务提交前,使用ROLLBACK TO SAVEPOINT savepoint
方式来回滚到指定的保存点。
事务隔离
MyISAM引擎使用了表级的锁定机制,确保不同客户端不能同时修改表。InnoDB引擎则提供了更细致的锁定方式:当一个客户端修改某个行的同时,另一个客户端可以读取和修改同表里的另一个行。
但另一个客户端能否读取正在进行的修改仍会产生问题。事务同时进行时可能出现脏读、不可重复读、幻影行的问题。为了解决这些问题,InnoDB提供了4中事务隔离机制:
- READ UNCOMMITTED:允许看到其他事务未提交的行修改;
- READ COMMITTED:允许看到其他事务已经提交的行修改;
- REPEATABLE READ:某个事务两次执行
SELECT
语句的结果是可重复的(相同的)。也就是说,该事务无法读取其他事务在同时插入或修改的行,即使已经提交; - SERIALIZABLE:与REPEATABLE READ类似,但隔离的更彻底。如果某个事务在读取某些行,那么在它完成之前,其他事务都无法对这些行进行修改。
隔离级别 | 脏读 | 不可重复读 | 幻影行 |
---|---|---|---|
READ UNCOMMITTED | 是 | 是 | 是 |
READ COMMITTED | 否 | 是 | 是 |
REPEATABLE READ | 否 | 否 | 否 |
SERIALIZABLE | 否 | 否 | 否 |
上表是4种隔离机制与三个问题之间的认可关系。
InnoDB默认的隔离级别是REPEATABLE READ,可以使用SET (GLOBAL/SESSION) TRANSACTION ISOLATION LEVEL level
来更改。
注意:非事务表永远子啊自动提交模式下(即便禁用了自动提交模式),所以在事务中对非事务表的修改将是无法还原的。
外键
[CONSTRAINT constraint_name]
FOREIGN KEY (column) REFERENCES table (foreign_column)
[ON DELETE action] [ON UPDATE action]
建立外键关系时有以下几点:
- 外键关系所涉及的两个表里的外键列必须被索引。
- 父表和子表索引里的对应列必须类型兼容。
- 不能对外键里的字符串列的前缀进行索引。
FULLTEXT搜索
全文搜索有3中类型:自然语言搜索(默认)、布尔模式搜索、查询扩展搜索。
全文搜索基于FULLTEXT索引。它会忽略掉“常见”(至少在一半的行里出现的)词。部分“停用词”(stopword)在全文搜索时总是会被忽略掉。
太短的单词(默认指少于4字符,可更改)也会被忽略掉。