15.5.4 BDB表的特征

每个BDB表用两个文件被存在磁盘上。文件的名字用表的名字做开头,并且有一个扩展名来指明文件类型。一个.frm文件存储表定义,一个.db文件包含表数据和索引。

要明确指出你想要一个BDB表,用ENGINE或TYPE表选项来指明:

CREATE TABLE t (i INT) ENGINE = BDB;
  
    
     
CREATE TABLE t (i INT) TYPE = BDB;
  
    
     

BerkeleyDB是用ENGINE或者TYPE选项的BDB存储引擎的“同义词”。

BDB存储引擎提供事务性表,你使用这些表的方法取决于autocommit模式:

·         如果你正运行着,同时随着autocommit的被允许(这是默认的),对BDB表的改变被立即提交并且不能被 回滚。

·         如果你正运行着,同时随着autocommit的被禁止,改变不变成永久的直到你执行一个COMMIT语句。作为提交的替代,你可以执行ROLLBACK来忘记改变。

你可以用BEGIN WORK语句开始一个事务来挂起autocommit,或者用SET AUTOCOMMIT=0来明确禁止autocommit。

请参阅13.4.1节,“START TRANSACTION, COMMIT和ROLLBACK语法”

BDB存储引擎有下列特征:

·         BDB表可以有多达每表31个索引,每个索引16列,并且1024字节的最大 键尺寸。

·         MySQL在每个BDB表中需要一个PRIMARY KEY以便每一行可以被唯一地识别。如果你不明确创建一个,MySQL为你创建并维持一个隐藏的PRIMARY KEY。隐藏的 键有一个5字节的长度,并且为每个插入的企图而被增加。这个键不出现在SHOW CREATE TABLE或DESCRIBE的输出之中。

·         PRIMARY KEY比任何其它索引都要快,因为PRIMARY KEY被与行的数据一起存储。其它索引被存储为键数据+PRIMARY KEY,所以保持PRIMARY KEY尽可能地短以节约磁盘空间并获得更好速度是重要的。

这个行为类似于InnoDB的,在其中较短的primary keys不仅在主索引也在第二索引节约空间 。

·         如果在BDB表中,你访问的所有列是同一索引的一部分或主键的一部分,MySQL可以执行查询而不访问确实的行。在一个MyISAM表中,只有 列是同一索引的一部分之时,才可以这么做。

·         连续扫描比对MyISAM表的扫描更慢,因为在BDB表中的数据被存储在B树而不是在分离的数据文件中。

·        键值象MyISAM表中的 键值一样不是前缀或后缀压缩的。换句话说,在BDB表中键信息只比在MyISAM表中稍微多占据一点空间。

·         在BDB表中经常有洞允许你在索引树的中间插入新行。这个使得BDB表比MyISAM表稍微大一些

·         SELECT COUNT(*) FROM tbl_name对BDB表很慢,因为在该表中没有行计数被维持。

·         优化器需要知道表中的大概行数。MySQL通过计数插入以及在每个BDB表中的单独片断内维持它来解决了问题。如果你不发出大量的DELETE或ROLLBACK语句,这个数对MySQL优化器来说是足够精确了。可是,MySQL仅在关闭的时候才存储这个数,所以,如果服务器被意外地终止,这个数可能是不正确的。即使数不是100%正确,它不是 明确的。你可以使用ANALYZE TABLE或者 OPTIMIZE TABLE语句来更新行计数。请参阅13.5.2.1节,“ANALYZE TABLE语法”13.5.2.5节,“OPTIMIZE TABLE语法”

·         BDB表上的内部锁定在页面级别上做。

·         LOCK TABLES在BDB表上就想在其它表上一样工作。如果你不使用LOCK TABLES,MySQL对该表发出一个内部多重写锁定 (一个不阻止其它作者的锁定)来确保即使另一个线程发出一个表锁定,该表也被恰当地锁定了。

·         要能够回滚一个事务,BDB存储引擎维护日志文件。多实现最高性能,你可以使用--bdb-logdir选项来把BDB日志放在不同的磁盘上,而不是放在数据库被放置的那个磁盘。

·         每次新BDB日志文件被启动之时,MySQL执行一个检查点,并且删掉当前事务不需要的任何BDB日志文件。你也可以在任何时候使用FLUSH LOGS来给Berkeley DB表设置检查点。

对灾难恢复,你应该使用表备份加MySQL的二进制日志,请参阅5.9.1节,“数据库备份”

警告:如果你删除仍在使用中的旧日志文件,BDB根本不能做恢复,并且如果有些事不对,你可能会丢失数据。

·         应用程序必须总是被准备来处理情况,即BDB表任何的改变可能导致一个自动回滚并且任何读可能会带着一个死锁错误而失败。

·         如果你在BDB表内遇到磁盘满,你得到一个错误(可能是错误28),并且事务应该回滚。这与MyISAM表相反,对于MyISAM 表,mysqld在继续之前等待足够的自由磁盘空间。

关注编程学问公众号