伯乐共勉

讨论。NET专区
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

InterBase/FireBird和Microsoft SQL Server之技术比较

Posted on 2007-08-29 16:53  伯乐共勉  阅读(916)  评论(0编辑  收藏  举报
目录:
介绍
为你的项目选择合适的数据库
数据的一致性与并发性
死锁
锁冲突
锁升级
触发器的灵活性
恢复速度
事件
培训时间
跨平台支持
成本
资源需求
发布与部署
特性
结论
介绍
 Borland InterBase和开源的FireBird是一个强大的、支持SQL语言的数据库, 她经常用于嵌入式开发和特定的应用软件中。聪明的开发者和架构师花些时间详细的了解下IB/FB就会发现,她确实有多处超越MSSQLserver的优势。这些优势包括:
 在混合读写环境下更加卓越的并发性;
 更灵活的触发器支持;
 更快的灾难恢复;
 更简单的事件管理;
 更多的部署选择;
 跨平台支持;
 小巧;
 系统要求更低;
 更短的培训时间;
 更低的培训费用;
 更低的许可费用;(FireBird完全免费)

 本文将详细讨论这些优势。
 今天的嵌入式和分布式数据库应用创造了一种环境——由短时间的读事务和更新事务 (典型的如数据录入系统)以及长时间读事务(如制作报表和数据分析)这两种情况组成。当数据分析要求马上在此刻得到一个一致的数据视图时,MSSQLServer必须加锁来防止其他用户存取正在分析的数据。
 IB/FB的数据库引擎专门设计成能够及时的为你的数据提供一个一致的快照,而不会阻塞其他用户的读和更新。在IB/FB中,读操作绝不会阻塞写操作,写操作只有当两个事务试图在同一时刻更新同一行时阻塞写操作。另外,IB/FB的并发模型是完全可预测的。使用IB/FB,绝不会有MSSQLServer里类似锁的任意升级导致整个表的存取被拒绝麻烦。
 IB/FB拥有嵌入式或需要远程部署的应用所需要的所有关键特性。 你的开发团队很容易学习和使用,很容易部署且在产品中几乎不需要维护。IB只有只有MSSQLServer最小安装大小的六分之一(FB更小),却提供了SMP支持,跨平台支持,先进的基于成本的查询优化,行级锁,从服务器灾难中即时恢复,事务支持在任何时刻及时提供一致快照的隔离级别,丰富的SQL方言,before和after两种触发器,完整的触发器触发顺序控制,存储过程,在线备份,在线修改元数据,复制,以及在客户端的应用程序中触发来自数据库触发器的事件。
 IB在三方面降低项目中的成本:
 1、IB的授权许可费用比MSSQLServer低(FB是完全免费开源的);
 2、需要更少的时间培训。一个MSSQLServer2000的DBA认证至少需要22天的课堂培训。 IB/FB学起来是如此容易以至于其培训课程只需5天,就可以使一个完全的数据库新手达到能够为IB/FB数据库提供信赖支持的程度。那些已经对基本的数据库管理熟悉的人会发现,不时查询一下Interbase的文档就是所需要的一切了。
 3、开发人员不必花时间寻找创造性的方法来写代码解决数据库的限制, 比如锁冲突,锁升级,缺少的"before"触发器,有限的触发器触发顺序控制和需要的事件
为你的项目选择合适的数据库
 建一个你的数据库项目需要的属性列表不是难事。 但仅依靠一个简单的特性列表来评估数据库是不够的。为你的应用程序选择一个正确的数据库时最关键的一步是调查在你的应用程序将会遇到的真实情形中,你所考虑的数据库的行为。本文调查了IB和MSSQLServer在许多情况下的行为,在当今的商业环境中你很有可能面对这些情况。

 数据的一致性与并发性
 假设你有一个存货管理系统,用于跟踪许多仓库中的产品条目。 在系统运行时,你的应用程序必须要出一个存货估价报表。使用读提交(read committed)的事务隔离,会发生下面的一系列事件:
 1、开始一个将要合计价值的读事务,从各个仓库收集条目;
 2、这个读事务扫描Abilene仓库的所有记录;
 3、另一个用户开始一个更新事物,从Abilene仓库移动1000金条到San Antonio仓库;
 4、更新事务提交;
 5、读事务读到San Antonio仓库的记录。这个读事务现在就把1000金条计算了两次, 一次在Abilene仓库,另一次在San Antonio仓库。
 在MSSQLServer中,通过给读事务使用Serializable(连续读)事务隔离很容易避免这个问题。 Serializable隔离模式保护你的事务在其生存期内不会看到由其他用户作出的改变。然而,要达到这种效果,MSSQLServer要么锁住整个表,要么在WHERE语句跨越的所有覆盖值的索引上放一系列锁 (引自Microsoft SQL Server 2000, Microsoft Press,799页)。 虽然这些锁比表锁限制少,但仍有很多本来不必要的行被禁止插入。考虑下面的SELECT语句:
 SELECT * FROM CUSTOMER WHERE CITY >= 'Charleston' AND CITY <= 'Los Alamos'
 假设在CITY列的索引中覆盖的WHERE语句的范围是Abilene, Detroit, and San Francisco这些节点,那么这些节点都会被锁住。不幸的是,这将意味着你不能插入这样一列,它的值大于Abilene而小于Charleston,即使WHERE语句没有包含这一行,因为它在锁的覆盖范围内。同样的原因,你也不能插入其值大于Los Alamos而小于San Francisco的行(引自Microsoft SQL Server 2000, Microsoft Press,776页 )。
 虽然数据的一致性达到了,但这也牺牲了并发性, 因为其他用户不能在行锁覆盖的行及表锁覆盖的表上插入和更新的记录。当分析和汇总大量的数据时
——比如上面的例子,在读事务结束之前,其他用户的插入和更新会一直被阻塞。
 在IB/FB中,由于IB的版本引擎机制,这个问题根本就不存在。回到库存估价的例子中,下面是IB/FB的情况:
 1、使用快照事务隔离机制,读事务开始;
 2、读事务扫描Abilene仓库的记录;
 3、另一个用户开始一个更新事务,从Abilene移动1000金条到San Francisco;
 4、更新事务发现一个更早的活动事务,于是为需要更新的记录创建新的版本;
 5、更新事务提交;
 6、读事务读到San Antonio中更新的记录。 读事务看到当前记录的版本是由一个在它之后开始的事务创建的,于是它往回扫描记录的版本,直到它发现一个在它开始时已经提交的版本,并读那个版本。
 通过读那些只在读事务开始时已经提交的记录版本, 不用禁止记录的更新,IB/FB就能提供一个逻辑上一致的数据视图。

死锁
 假如用户A执行一个SELECT语句读Parts表中的所有行。用户B也SELECT了Parts表的所有行。两个用户都要获得各自所选数据的一个稳定一致的视图。用户A试图更新part=100的记录。用户B试图更新part=101的记录。
 MSSQLServer会使用重复读或serializable事务隔离,这种情况将导致死锁,即使两个用户更新的是不同的行。怎么会呢?A在读记录时得到表上的一个共享锁。B也一样。当A更新part=100的记录时,必须得到这一行的排他锁,于是把他在表上的共享锁转换成意向排他锁。然而,意向排他锁和B的共享锁冲突,所以无法得到(引自Microsoft SQL Server 2000, Microsoft Press,799页 )。同样,当B要更新part=101的记录时,因为A的共享锁,B也不能把他在表上的共享锁转换成意向排他锁。这就是所谓的转换死锁(见Microsoft SQL Server 2000, Microsoft Press,776页 )。
 在IB/FB中不会发生锁转换。IB/FB只会在更新时锁住个别的行。IB/FB只会发生一种类型的死锁就是循环死锁(所有数据库都存在),也就是当用户A更新并锁住了行100,然后试图更新已经被用户B加锁并更新的行200,同时,用户B也试图更新已经被A加锁的行100。这种情况下,会发生下面两种情况之一。如果有用户在他们事务中指定了NoWait选项,那么当A试图给B已经锁住的行加锁时,会立即返回错误信息,反之亦然。如果两个用户都选择了等待加锁的行,那么锁管理器将检测到死锁并选择一个事务让其回滚。

 锁冲突
 考虑这样一种情形,当用户A对一行进行了更新操作但没有提交事务,然后A去吃午饭了。用户B执行一个包含此加锁行的SELECT操作。
 使用MSSQLServer,用户B的事务将一直等待,直到用户A持有的锁释放为止(MSDN-Locking Architcture at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/architec/8_ar_sa2_2sit.asp )。“缺省设置下,没有强制超时期,也没有办法在加锁之前测试出释放的资源是否被锁,除非企图存取数据(潜在得到不确定的阻塞)”(见Microsoft SQL Server 2000 Books Online, LOCK_TIMEOUT Setting)。“为了预防这种不确定的等待,需要设置锁的超时期,使用SET LOCK_TIMEOUT命令,但这个设置会影响连接中所有事务”(见Microsoft SQL Server 2000 Books Online, SET LOCK_TIMEOUT)。
 IB/FB限制更少且更灵活。使用快照事务隔离(snapshot),你一直读的是事务开始时已经提交的行的最新版本。使用读提交(read committed)事务隔离,IB/FB给你三种选择:
 1、读这一行最新提交的版本即使有未提交的版本存在;
 2、等待,直到未提交的版本也提交或回滚,然后读这一行;
 3、立即接收到一个异常警告:存在此行的一个未提交版本;
 这些设置在事务级别,因此同一连接中,你为某一个事务的所作的设置不会限制到你为其他事务的所作的选择。
 锁升级
 设想你正在开发一个订单录入系统。订单条目表会包含上百万条记录。你必须能够通过客户类型和销售地域中的条目为某一时期生成销售报表,报表必须基于一致的数据视图。生成年报表将在订单条目表中选择超过百万的记录。
 “当一个事务超过升级上限时, MSSQLServer2000会自动升级行锁和页锁。比如,当一个事务需要表中的一些行时, SQLServer自动获得这些行的锁,并在包含那些行的页、表或索引上放置更高级别的意向锁。当事务持有的锁的数量超过其极限时,SQLServer会企图把表上的意向锁变为更强的锁(如意向排他锁转为排他锁).获得更强的锁后,所有此事务持有的页级和行级锁被释放,锁开销减少了。”(见http://msdn.microsoft.com/library/default.asp?url=/library/en-us/acdata/ac_8_con_7a_5ovi.asp, Lock Escalation )锁升级的结果是整个表对其他用户不再可用。在本例中,记录上的共享锁将升级为一个表上的共享锁。于是其他所有用户都不能更新此表中的任一行。如果要更新一个表中的大量行,那么更新需要的排他锁可能升级为表级锁,以防止其他用户读和更新这张表。
 IB/FB的版本体系结构在读记录时不需要任何锁。通过记录的不同版本,一致性的数据视图不需要放置锁,更不会阻塞其他更新操作。IB/FB的锁只是行级别的,且只在更新一行时存在,所以根本不存在锁升级的概念。


触发器的灵活性
 当给数据库添加新客户时,系统必须自动指定其销售区域和销售代表。为了指定正确的销售区域,应用程序必须从State表中查找用户所在的州,然后用销售区域和客户的分类代码查找Sales Rep表。理想的解决方案是给Customer表添加一个Before Insert触发器, 在记录插入Customer表之前添加销售区域和销售代表号码。
 MSSQLServer没有在事件之前激活的触发器,只能附在INSERT,UPDATE或DELETE事件之后激活(见Microsoft SQL Server 2000, Microsoft Press,657页)。 为了解决上面提到的问题,可以使用所谓instead-of触发器。这种触发器激活后取代它所附属的事件。在本例中,将激活这种触发器,但那条新的客户记录不会被插入到数据库中。因此,触发器不仅要决定销售区域和销售代表,还要执行把新客户记录插入数据库中的INSERT语句。这使得触发器很复杂,时间也浪费在写触发器上了。
 更不幸的是,instead-of触发器还有其他限制。每个事件只能有一个instead-of触发器。不能用多个触发器来模块化你的代码,以便容易维护。Instead-of触发器也不能和某些外键一起使用——这些外键给触发器所依附的事件设置了级联选项。比如,如果某个表有一个设置了级联删除的外键,instead-of触发器就不能出现在这个删除事件中。
 IB/FB给INSERT,UPDATE和DELETE同时提供了before与after触发器。每一事件的触发器数量没有限制,在触发器和外键约束之间也没有任何冲突。
 同一事件的多个触发器能使代码模块化,便于测试和维护。然而,对于触发器执行的顺序,MSSqlServer只提供了很有限的控制。你能指定某一触发器第一个触发或最后一个触发,但仅此而已。一旦触发器必须独立于触发顺序,那么它们写起来很复杂且不够灵活。
 IB/FB可以制定触发器执行的精确顺序。在触发顺序的任一点,随时能够很容易的插入新的触发器。
 对于MSSqlServer来说控制触发器中的错误很难。一旦触发器在事件之后触发,撤销触发器执行的INSERT,UPDATE或DELETE操作的唯一方法就是回滚事务。由于一个致命错误或请求回滚事务,触发器内的回滚中止了整批SQL指令,而不仅仅是那些由触发器做的修改(见Microsoft SQL Server 2000, Microsoft Press,687页)。
 IB/FB中,若before触发器产生异常,之前发生INSERT,UPDATE或DELETE将会中止。IB/FB也允许在触发器激活时创建指定的还原点(savepoint)。你可以随时回滚到任一还原点。比如,更新前(before)触发器中创建一个还原点,然后在更新后(after)触发器中回滚到这个还原点,从而使该还原点后的所做的修改(包括触发此触发器的UPDATE本身)撤销了。不只是在存储过程和触发器中,还原点在事务的任何时候都可用。


成本
 应用软件也许分布在许多地方或支持许多用户,当使用到数据库时,数据库本身的许可费用会变为项目开支的一个重要部分。下面的表格比较了IB与MSSQLServer2000标准版的费用。IB在每一类中都更加实惠。 (注:由IB开源而来的FB是完全免费且源代码公开的,即使在商业用途中,也是如此)
用户数  CPU个数  Borland InterBase  MSSQLserver2000标准版
20  1  2300美元(下同)  4498美元(下同)
20  2  3300  4498
50  1  3700  4999
50  2  4700  9998
50  4  6700  11245
100或200  1  4199  4999
100或200  2  5199  9998
100或200  4  7199  19996







 资源需求
 减少部署费用的一个方法是通过网络发布你的应用软件。另外,你也许同样希望能减少部署地点的硬件升级所需的开支。
 MSSQLServer2000需要“97到270兆的可用硬盘空间,典型安装需要250兆”。Windows2000下需要64兆内存,WindowsXP下需要128兆内存。(见http://www.microsoft.com/sql/evaluation/sysreqs/2000/default.asp)
 IB完全安装需要不到40兆的硬盘空间。如果你不安装文档和例子,那么安装少于15兆(FB所需更少)。此外在所有平台下,运行IB只需要32兆的内存。

 部署与发布
 你或许想把数据库服务器和客户端的安装集成到应用软件里,使安装部署更容易。
 但你必须使用Microsoft提供的安装包来安装MSSQLServer。“SQLServer的安装程序写注册表,改变系统路径和多处系统设置,创建程序组和用户账户,并为其使用执行基本的初始化配置。安装程序远非仅仅拷贝文件。对于你来说,作为服务或产品的一部分创建自己的程序来安装SQLServer是不现实的(见Microsoft SQL Server 2000, Microsoft Press,166-167页)。”
 与之相比,IB/FB给了你完全的灵活性。你可以使用本身的安装包,也可以用其他安装打包软件,或者干脆自己写安装程序。


MSDE
 也许,作为使用MSSQLServer的另一种选择,你会考虑使用MSDE来部署发布应用程序。
 MSDE就是SQLServe2000,拥有其所有特性和限制。MSDE还有三个额外的限制。“为了达到最佳性能,有一个限制在五个并发工作量的并发量管理器”, “若超过五工作量的限制,并发管理器会使系统不断的慢下来”(见http://www.microsoft.com/sql/msde/productinfo/features.asp)。每一条工作量是一个连接,如果每一个用户需要两个连接,那么MSDE就只能支持两个用户。MSDE需要44兆的硬盘空间,2000下64兆内存,XP下128内存。(见http://www.microsoft.com/sql/evaluation/sysreqs/2000/default.asp)
 “MSDE支持2G以下的单个数据库。”——注意不是每个表。这是第二个额外限制。这也就是说你的所有数据,元数据,索引,临时表,存储过程和触发器加一起必须在2G以内。
 “MSDE2000包括一些供管理实例的命令”(见http://www.microsoft.com/sql/msde/productinfo/features.asp) ——MSDE不提供任何MSSQLServer的GUI工具来设计和创建数据库,管理服务器,测试查询和调整服务器的性能。
 “几个Microsoft的产品有权许可转让使用和重新发布MSDE2000”(见http://www.microsoft.com/sql/msde/productinfo/features.asp) 获得的这些权力很复杂,而且依赖你购买的获得MSDE2000的Microsoft产品。有些产品不包括重新发布的权力。其他能重新发布的需要满足多方面的条件。

 特性
 下面的表格比较了IB/FB和SQLServer的特性。这个表单并不完全,但是集中了重要的特性,如远程部署的嵌入式应用、长时间读事务间杂着更新事务组成的应用。
特性  InterBase/FireBird  SQL Server
事务支持  是  是
SQL支持  是  是
用户自定义函数  是  是
基于成本优化  是  是
提供不会阻塞更新的一致数据快照  是  否
行级锁  是  是
不存在锁升级  是  否
不存在转换死锁  是  否
快照事务隔离  是  是
两段式提交  是  是
支持多用户和单用户  是  是
支持SMP  是  是
存储过程  是  是
before触发器  是  否
after触发器  是  是
触发器触发顺序控制  是  否
触发客户端事件  是  否
自动生成键  是  是
支持所有数据类型取空值  是  是
参照完整性  是  是
在线备份  是  是
在线更改元数据  是  是
复制  是  是
即时灾难恢复  是  否
零维护  是  是
定制安装包  是  否
内存需要  32MB  2000下64MB,XP下128MB
硬盘空间  40MB(包括文档和例子),否则不到15MB  平均250MB


结论
 IB/FB是你拥有:
 混合读写环境中卓越的并发性;
 更灵活的触发器支持;
 更快的灾难恢复;
 更容易的事件管理;
 更多的部署选择;
 跨平台支持;
 小巧;
 系统要求更低;
 更短的培训时间;
 更低的培训费用;
 更实惠的许可费用...
 IB/FB以最低的成本和最短的时间,提供了创建强大应用所需要的特性。

 作者简介:Bill Todd是Database Group, Inc.(Phoenix旁边的一个数据库咨询与开发公司)的总裁。合著过4本数据库编程方面的书籍,发表超过100篇文章。在美国和欧洲的开发者大会上提交了超过20篇论文。