Mysql数据库应该是互联网应用中使用范围最广的关系型数据库了,没有之一。它的插件式存储引擎架构非常有意思,不同的引擎有着非常不一样的功能和特点。当然针对不同的应用场景需要选择不同的引擎来处理,一些常见常用的比如MyISAM,InnoDB,NDB,Memory等。虽说各个存储引擎对应用是透明的,但是使用mysql时我们仍然需要了解它们各自的特点。
下面简单列举各个引擎的特点
- InnoDB存储引擎——支持事务,主要用在OLTP(在线事务处理),特点是支持行级锁,支持外键。
- MyISAM存储引擎——Mysql官方默认的存储引擎,特点是不支持事务,提供表锁,全文索引,适合OLAP的应用。
- NDB存储引擎——一个集群存储引擎,数据存储在内存中,5.1版本可将非索引数据存于磁盘
- Memory存储引擎——表中的数据放在内存,适合存储临时表
- Archive存储引擎——只支持insert和select操作,使用zlib算法压缩数据,用于归档数据,日志信息存储
- 其它
通过下面的命令可以查询到我们的mysql服务支持什么类型的引擎
mysql> show engines;
+------------+---------+------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+------------+---------+------------------------------------------------------------+--------------+------+------------+
| CSV | YES | CSV storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance | NO | NO | NO |
+------------+---------+------------------------------------------------------------+--------------+------+------------+
5 rows in set (0.00 sec)
查看一个数据表是什么引擎可以用show create table [tblname]来查看,更改数据表的引擎方式可以用下面的语句
mysql> alter table test engine=InnoDB;
Query OK, 2 rows affected (0.51 sec)
Records: 2 Duplicates: 0 Warnings: 0
做了上面一些简要介绍,我们来具体看看innodb存储引擎的事务吧。事务是数据库有别于文件系统的重要特性之一,我们平时写文件时如果系统崩溃,文件很有可能就会被破坏了。而数据库在提交工作时,保证要么对文件的修改全部成功,要么就不做修改,这就是事务的特点。
在mysql命令行默认设置下,事务都是自动提交,我们可以用下面的控制语句来测试
BEGIN 开始一个事务
COMMIT 提交事务
ROLLBACK 结束事务,撤销修改
还有其他一些命令
SAVEPOINT identifier创建保存点
RELEASE SAVEPOINT identifier 删除保存点
ROLLBACK TO [SAVEPOINT] identifier 回滚到保存点
SET TRANSACTION 设置事务的隔离级别
我们来创建一个表来测试一下控制语句
mysql> create table ceshi(id int,primary key(id)) engine=innodb;
Query OK, 0 rows affected (0.03 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into ceshi select 1;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from ceshi;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
我们再在表中插入分别数字2,3,1,结果在插入1时发现已经存在此主键,插入失败,通过rollback回滚,2和3的插入也没有生效。
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into ceshi select 2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into ceshi select 3;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into ceshi select 1;
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from ceshi;
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
我们用pdo_mysql.so扩展来实现php操作mysql事务也很方便,同样需要用到上面的控制语句。为了方便演示,我用以前的一篇博客中封装的
mysql操作类代码如下:
<?php
include("mysql.php");
$my = new EasyMysql();
$my->query("BEGIN");
$res1 = $my->query("insert into ceshi select 2");
$res2 = $my->query("insert into ceshi select 3");
$res3 = $my->query("insert into ceshi select 1");
if($res1 && $res2 && $res3)
{
$my->query("COMMIT");
echo "insert success";
}
else
{
$my->query("ROLLBACK");
echo "insert failed";
}
$res = $my->query("select * from ceshi");
print_r($res);
?>
我们检测一族sql操作的结果,如果某个操作失败则回滚,都成功则提交,这样可以保证数据库操作的原子性。通过浏览器访问页面,可以看出因为数字1已经存在,数字2和3也都没能插入到数据库中(
程序脚本就算中途退出,只要没有commit操作也不会更改数据库)。就通过这些简单的代码就能直接使用innodb的事务特性了,很简单易用。