DBISAM与BDE的不同点之处
应该被指出,BDE和DBISAM有几个非常关键的差异,特别是当你要把已经使用BDE的应用程序转换为DBISAM时。请注意,这里所有的对比都是假定仅仅在BDE可用的Paradox和dBase/FoxPro本地数据库基础上,因为很多原因在比较时没有包括Access。
BLOB:
BDE(在Paradox数据库中)允许存储部分BLOB数据到一个给定的在实际数据记录中存储的BLOB字段,除非你存储BLOB到一个独立的BLOB文件。DBISAM不支持这么操作,而是更像dBase那样把所有BLOB数据单独存储在一个独立的BLOB文件中。DBISAM总是在记录被增加或编辑时缓存BLOB在内存中,相比起来,BDE一般在BLOB数据超过内存消耗可接受限度时,把它们保存在磁盘上的临时文件里(可接受限度由BDE 决定)。
数据备份:
DBISAM目前没有batch move组件,但是通过SQL INSERT和UPDATE语句提供大量的插入和更新,同样能达到目的。
高速缓存更新:
DBISAM也不支持高速缓存更新。同样,你也可以通过内存表和事务轻松达到同样的功能。
并行操作(多用户):
一般说来,BDE很难适当设置为多用户使用,尤其是Paradox。这需要处理.NET文件、.LCK文件和设置本地共享,如果设置不恰当就会导致数据刷新困难,严重时导致数据毁坏和数据丢失。使用DBISAM,所有的锁定均由操作系统完成,而不需要涉及任何外部配置文件。你不需要为单用户和多用户做任何额外的工作,所有难做的工作都已经替你做好了,你惟一要做的就是把表复制到网络服务器上。
如果手工刷新没有执行,BDE一般不会提供本地缓存里的新数据,所以不同的客户可能会看到不同的数据。DBISAM允许你通过 TDBISAMSession组件的StrictChangeDetection属性选择怎样提供数据流。使用严格的改变检测 (StrictChangeDetection=True)可以确保DBISAM总是返回新数据。使用延时的改变检测 (StrictChangeDetection=False)会导致DBISAM不一定返回新数据,这和BDE的默认特性一样,但是性能却大大提高!延时的改变检测是TDBISAMSession组件的默认属性,然而,BDE和DBISAM(使用延时的改变检测)都会确保使用新的数据更新数据库。 DBISAM的改变检测选项也能由同一个应用程序中的多个TDBISAMSession组件混合决定。
分发:
DBISAM可以完全编译到你的应用程序中而不需要任何其他DLL或附加控件,运行期包也为Delphi3分发DBXXXXXR.DPL,为 Delphi4/5分发DBXXXXXR.BPL并为C++Builder 3/4/5提供支持(这里的XXXXX前三位由DBISAM的3位版本号替换,比如200就是2.00版,再用一个D表示Delphi或一个C表示 C++Builder,后一位表示一个版本号,比如3表示Delphi3)。
加密和用户安全:
BDE通过把Paradox用户口令加密而包含用户安全支持。DBISAM也支持用口令对一个表进行加密,但是目前不支持基于用户的加密机制。每当你尝试对一个加密的DBISAM表进行任何操作时,你就会被提示需要口令。你必须特别注意这个功能,因为你可能会因为忘掉口令而不能打开一个加密表。
过滤:
BDE和DBISAM都提供条件过滤和基于OnFilterRecord事件描述的过滤机制,因此你可以过滤任意类型的数据。无论是BDE还是 DBISAM,条件过滤都是由数据库引擎进行优化。这就是说,一个部分或全部符合过滤条件的可用索引(不管主从)总是找到合适的记录,而不是从上到下对实际数据记录进行扫描。不管是BDE还是DBISAM都要记住:FilterOptions属性设置的ixCaseInsensitive影响着哪一个索引对这个优化过程有效(大小写敏感和大小写不敏感),但是这仅仅针对String字段来说。如果对一个非字符串(如整型)字段设置过滤,ixCaseInsensitive设置就和优化过程无关。如果你想弄清楚一个特定的过滤是否可优化,只要检查TDBISAMTable组件的 FilterOptimizeLevel属性就行。DBISAM用bitmaps和索引执行过滤优化使用了Rushmore技术,这一点与FoxPro和 dBase使用的技术差不多。符合过滤条件的记录次序和BDE的记录计数完全一样。
空闲空间管理:
BDE在Paradox中实行剩余空间循环利用,在FoxPro和dBase中却不能循环利用,这些数据库表经过多次插入和删除操作后将会趋于臃肿。这是首要的一点,因为这些格式的记录不是被物理删除而是被作了删除标志,相应的索引关键字也被保留在索引文件里。除非必须的用户干预,DBISAM 在数据、索引和备注文件中循环利用空闲空间,当一条记录被删除时,空间被腾出并可以立即再使用。TDBISAMTable组件的 OptimizeTable方法允许你充分利用一个表作为特定的索引顺序(如合计表),充分利用BLOB,从数据、索引和备注文件中移出空闲空间。
内存表:
BDE允许建立一个像正常表一样的内存表,但是有些地方有某些限制,比如增加和使用索引的能力及使用BLOB字段的能力。通过BDE建立的内存表会自动释放而且不能被多个TTable组件共享。利用内存表的底层BDE调用对大部分Delphi和C++Builder初学者来说是非常混乱的。另一方面,DBISAM突破了这些限制,它甚至允许内存表,被多个TDBISAMTable组件共享。使用DBISAM内存表只要设置相应的 TDBISAMTable组件的InMemory属性的布尔值即可。注意:DBISAM中使用内存表就和实际表一样,你必须首先用CreateTable 来建表和用DeleteTable来释放表。DBISAM还允许批处理内存表,只要是继承TStream,使用TDBISAMTable组件的 SaveToStream和LoadFromStream方法。这意味着你可以建立聚集在一条记录里的BLOB字段之外的内嵌表。
索引:
BDE通过独立的驱动程序支持对本地数据库使用多个不同的索引表。DBISAM像Paradox表一样支持主从索引,但是不具有某些 FoxPro的.CDX和dBase的.MDX的特征。Paradox、FoxPro、dBase和DBISAM表都有不一样的地方,以下是BDE本地数据库和DBISAM数据库的不同点。
一、主索引
Paradox允许表定义为没有主索引,DBISAM同样也支持。
二、大小写不敏感
Paradox支持从索引的大小写不敏感索引,DBISAM同样也支持,而且还支持主索引的大小写不敏感索引。
三、从索引
Paradox存储每一个从索引于一个单独的文件,这是主索引外的一个附加文件。DBISAM存储所有的主从索引在一个.IDX文件中,这样就减少了文件句柄使用和分发的麻烦。
四、关键字压缩
Paradox和dBase的.MDX根本不包括任何类型的关键字压缩,FoxPro的.CDX却能很好地包括关键字压缩。DBISAM允许你选择双字节压缩、结尾字节压缩或全压缩(两种类型的压缩结合); FoxPro的.CDX允许使用全压缩,但是却不能选择压缩方法。
五、降序索引
Paradox 7.0以上允许降序从索引,DBISAM也支持降序索引,而且主从索引都支持。除了索引格式,BDE还支持索引基础上的几个特征检索,并可以设置需要注意的检索范围。
六、部分字段检索
BDE允许你对整个活跃索引的部分字段进行检索。例如,有一个Paradox表,主索引包含CustomerNum、 OrderNum和LineNum字段,你可以只在CustomerNum字段检索你需要的记录。这一点和DBISAM一样。
七、部分字段范围
BDE允许你在设置一个表的范围时使用该原则,DBISAM也支持该原则。
八、本地记录#标记
使用BDE的Paradox表可以检索基于当前活跃索引的本地记录号,DBISAM同样支持。
九、记录计数
Paradox允许得到一个瞬时的记录计数,即使这个范围是当前设置的;DBISAM同样支持。
国际化支持:
DBISAM提供超过100种语言支持,并能正确排序这其中任意一种语言。语言ID和排序ID能按照一个表或同一个应用程序中的多个多语言表明确分清。要注意的是排序ID中的多个排序仅仅对少数语言可用,大部分语言只支持一个排序ID——默认的排序次序。使用DBISAM的数据库系统应用程序,也可能基于语言设置对一个表使用恰当的日期、时间以及数据格式进行排序。
DBISAM提供的国际化支持是以Windows 95、Windows 98和Windows NT下的Win32 API里的本地设备为条件的。由于这个原因,一个特定语言的Windows操作系统只能使用特定的语言,比如俄语只能在俄文的Windows 95下使用。如果在一个没有安装特定语言支持的计算机上试图打开或新建一个表,DBISAM将会引起异常。不过要注意,Microsoft已经在 Windows 2000所有语言版本下提供了所有语言的国际化支持。
底层API调用:
完成某些特定任务,BDE需要调用底层API,比如重建表、批处理时向用户提供进程信息、复制要求冗长的表和隐含大量代码完成要求的任务。通过 TDBISAMTable组件,DBISAM提供了有大量文件证明的易用的属性、方法和事件,完全抛弃了调用任何API的需求。
内存使用:
DBISAM不能像BDE那样为数据、索引和备注缓存预分配内存。比较而言,DBISAM只为存储按照需要分配内存,而且有如下限制:
一、数据记录缓存
记录缓存的大值是128K。
二、索引页缓存
每一个索引的索引页缓存的大值是64K。例如你定义了4个索引(一主三从),那么DBISAM使用的大内存就是(64K * 4) = 256K。
三、备注缓存
备注缓存的大值是128K。
请记住:上面的数字是基于同一个会话期打开的每一个物理表。不同会话期打开的表使用不同的内存,因此会增加内存使用。比较而言,如果在同一个会话期多次打开同一个物理表,DBISAM将会使用同一个缓存,并在每个打开表的事例中-共享此缓存。
NULL 支持:
DBISAM与Paradox一样包含所有的NULL支持,尽管这已经由更安全和更周密的方法实现了。DBISAM对NULL支持的规则如下:
一、一个没有赋值的字段为NULL。
二、只要一个字段被赋值,它就不再被认为是NULL,但是String字段和BLOB字段是一个例外。当你给一个string字段赋值为空字符串时,它被认为是NULL;当一个BLOB字段内容为空,如长度为0时,它被设置为NULL,这就和调用TField的Clear方法一样。
三、调用TField的Clear方法将会使该字段为NULL。
四、NULL值在当作索引关键字时被当作一个独立的、与众不同的值。如果你有一个主索引由integer字段构成,这个字段的某一个记录值为 0,另外有一些记录值为NULL,DBISAM不会报告关键字非法错误。这是非常重要的一点,我们在设计表时应该反复考虑。作为一般的经验规则,你应该总是为主索引的一部分字段赋值。
五、自增字段值不会是NULL。
性能:
DBISAM与BDE不一样,它自动处理变化检测,这也导致它们性能的不同。对于Paadox表,BDE只有在需要完全读取磁盘数据和捕获数据记录锁定时检测磁盘变化(随后刷新本地缓存)。对于dBase表和FoxPro表,除非强制完全读取磁盘数据或捕获数据记录锁定,BDE不会刷新本地缓存。相反的,如果你把活动的TDBISAMSession组件的StrictChangeDetection属性设置为True,DBISAM总是在其他用户进行读写操作之前检测变化,以便使本地缓存总是包含新的数据。这意味着由于DBISAM自动处理变化检测,每一次批量的读取记录里大部分数据的过程会导致大量的I/O读取。解决这个问题的办法就是批量读取时锁定相关的表,或者使它不能自动处理变化检测(StrictChangeDetection=False)。
DBISAM在写操作时也自动处理变化检测,这就导致每一次批量的写入记录里大部分数据的过程会引起一些I/O开销。解决这个问题的办法就是一次包装上百次的更新到一个事务里。使用事务会使表维持写锁定,直到该事务被提交。不过,由于事务完全是在内存里处理的,所以性能将会和一个表已经被专门打开差不多。 后,BDE有一个本地共享设置,决定写操作是否为共享表缓存。如果一个程序被非正常关闭,本地共享设置为False将会导致灾难性的后果,因为它会使所有更新数据永远丢失。相反地,DBISAM绝不会为共享表缓存写操作,它总是在每一次更新后通知操作系统保存所有更新到磁盘上。如果你希望确定操作系统同步更新到磁盘上(有些操作系统,如Windows 95会短期缓存写操作),你可以用TDBISAMSession组件的FlushBuffers方法或ForceBufferFlush属性做到这一点。如果仅仅用DBISAM操作一个表,DBISAM会缓存所有写操作,这样会取得佳性能。然而,一些应用程序的意外终止会使所有更新数据永远丢失,就和 BDE的本地共享设置为False差不多。
查询(SQL和QBE):
DBISAM完全支持使用SQL SELECT、INSERT、UPDATE、DELETE、CREATE TABLE、ALTER TABLE、DROP TABLE、CREATE INDEX和DROP INDEX语句进行查询,这些几乎完全遵从BDE中的本地SQL句法。DBISAM目前不支持的SQL语句有:
一、UNION从句
DBISAM不支持UNION从句。
二、FULL OUTER JOIN从句
DBISAM不支持FULL OUTER JOIN从句,尽管它完全支持RIGHT OUTER JOINs和LEFT OUTER JOINs。
三、ANY或EXISTS算符
DBISAM不支持在WHERE从句中使用ANY或EXISTS算符进行下级选择判定。然而,DBISAM允许在SQL SELECT语句中使用IN操作符进行下级选择。
DBISAM还提供很多附加的特性和优点,这是BDE中的本地SQL句法所没有的。请参阅此手册的SQL参考部分,以得到附加句法的更多信息。
DBISAM不支持使用QBE进行查询。
后一点,BDE分发隐含的SQL错误信息,所以通常在一个出现错误的SQL语句中提供少数的或几乎不提供标志。DBISAM总是提供完整的描述性的错误信息,这样可以指出在SQL语法中错误发生的地方。
存储过程:
DBISAM不支持存储过程,但是它通过TDBISAMQuery组件的SQLScript属性和ExecSQLScript方法支持DDL SQL脚本。这样你可以写出包含多个CREATE TABLE、ALTER TABLE、DROP TABLE、CREATE INDEX、DROP INDEX、INSERT、UPDATE或DELETE语句的脚本,只要把它们之间用分号隔开。
事务支持:
BDE对本地数据库的参与已知事务的记录数量有一些限制,目前多可用255条记录,这还取决于你是使用Base/Foxpro还是使用 Paradox。DBISAM没有对事务处理加以任何限制,你可以使用内存允许的任意多条记录参与一个事务。不像BDE对本地数据库使用基于日志的事务处理系统,DBISAM完全在内存里处理事务,它缓存一次事务的所有更新。直到事务被提交,这些更新没有被写到磁盘上,所以事务被滚回也不用担心数据丢失。在提交过程中,DBISAM自动通知操作系统同步写操作到磁盘。为了完成这个任务,DBISAM必须对事务中更新的任何表捕获并保留写锁定。直到事务被提交,该写锁定一直有效,同时其他用户不能更新该表,尽管他们既能捕获锁定也能读取数据。这一点意味着你应该使事务越短越好。DBISAM中缓存事务是非常高效的,如果一次提交上百条记录来批量更新一个或多个表,缓存事务是一个的提高性能的办法。
请牢记:BDE和DBISAM都不提供自动防止失败的事务处理,所以不要指望它们防止在影响多个文件的复杂事务中出现的数据不一致,除非你确保应用程序不会被意外打断。DBISAM能稍微防止这类问题,这归功于它的缓存事务设计,但是程序提交过程被意外打断还会出现这些问题。
相关文章