维护数据库 (SQL Server Compact Edition)

使用一段时间后,Microsoft SQL Server 2005 Compact Edition (SQL Server Compact Edition) 数据库的内部结构会有很多碎片,这会造成磁盘空间浪费。如果碎片过多,性能就会降低。为避免碎片,请使用以下功能来维护 SQL Server Compact Edition 数据库。

有关如何使用本主题中介绍的方法和属性的详细信息,请参阅 System.Data.SqlServerCe 命名空间对象

压缩

您可以使用 Compact 方法(在本机编程中为 CompactDatabase 方法)回收数据库文件中的空间。您还可以使用它来更改数据库设置,例如密码和区域设置 ID (LCID)。

SQL Server Compact Edition 数据库文件被分割为许多大小为 4 KB 的逻辑单元(称为页)。随着数据库被不断地修改,有些页便可能包含未使用的空间,并且还有些页未得到利用。未使用的页最后通过 AutoShrink 机制进行回收。有关详细信息,请参阅本主题内下文中的“自动收缩”部分。

页上的未使用空间只能使用 Compact 方法进行回收。Compact 方法从源数据库读取行并把这些行写入目标数据库,它能够最大限度地减少目标数据库浪费的空间。

注意:
如果没有为目标数据库指定 Data Source 属性,Compact 方法将使用新的压缩数据库覆盖源数据库,数据库名称不变。

压缩数据库时:

  • 将重新创建一个新的数据库并创建新的索引。
  • 将重新组织表页,使它们驻留在相邻的数据库页中。这可以减少数据库中的表碎片,进而改善空间分配。
  • 通过将所有数据库数据重写到新的数据页中,回收由对象删除和记录删除产生的未使用的空间。当对象或记录从数据库中删除后,它们占用的空间将被标记为可用,可用于向数据库中添加数据。除非整页数据被完全删除,否则页便保持为部分填充状态。直到从数据库页上删除最后的数据或者压缩数据库后,数据库才会收缩。对于在其中频繁地添加、删除和更新对象和记录的数据库,我们建议您经常压缩它们。
  • 增量标识列被重置,以使分配的下一个值比所保留记录中的最高值大一个步长值。例如,如果数据库中的所有记录均已被删除,对数据库进行压缩便会将下一条记录的标识列的值设为种子值。如果数据库中保留的最高标识值为 50,步长值为 5,对数据库进行压缩会将下一条记录的值设为 55。即使以前添加过包含值大于 50 的记录,但只要在压缩之前已将其删除了,情况也是如此。步长值还可以是负数(例如 –5),其最小值为 15。对数据库进行压缩会将下一条记录的值设为 10。
    注意:
    如果使用的是原始版本的 Microsoft Visual Studio 2005,则会发生此行为。压缩数据库时,不会更改 Visual Studio 2005 SP1 中的标识信息。
  • 如果某些值被指定为目标数据库连接字符串中的区域设置标识符或密码,这些值将被用于创建目标数据库。

在压缩数据库前,请确保满足以下条件:

  • 数据库处于关闭状态。
  • 调用 Compact 方法时,目标数据库不存在。如果由 DestConnection 指定的数据库已存在或者已有一个同名文件,便会发生错误。
  • 除了要有足够的存储空间供所有缓存数据和临时数据库中存储的数据使用外,还要有足够的存储空间供原始版本和压缩版本的数据库使用。
重要事项:
若要使用 Compact 方法,您的设备的可用空间至少必须是源数据库大小的两倍。

自动收缩

若要压缩一个数据库,您首先要创建一个新的数据库,然后将所有对象从源数据库复制到新数据库。通常情况下,压缩不会自动启动。自动调整数据库文件的大小称为 AutoShrink。该技术几乎不占用处理器时间和内存,因此它特别适合手持式设备和移动数据库产品。Autoshrink 技术可以移动文件内的页,将所有的空白页或未分配的页相邻着放置在文件的末尾。然后,空白页会被截断。此后被截断的页可由数据库文件系统使用。将截断的页返回给数据库文件系统可以增加文件系统的空间。

若要设置 Autoshrink,对于托管代码,请使用 AutoShrink Threshold 连接字符串属性。对于本机代码,请使用 DBPROP_SSCE_AUTO_SHRINK_THRESHOLD 属性。该属性指定在 Autoshrink 启动前文件中的可用空间的百分比。

注意:
您还可以通过调用 Shrink 方法来收缩数据库。有关详细信息,请参阅 System.Data.SqlServerCe 命名空间对象

验证

SQL Server Compact Edition 数据库文件被分割为许多大小为 4 KB 的逻辑单元(称为页)。当每个页面被写入数据库文件时,SQL Server Compact Edition 将计算并保存该页的校验和。如果将页写入文件后该页被修改或损坏,则它将不再匹配它的预期校验和。SQL Server Compact Edition 在读取该页时,将返回本机错误 SSCE_M_DATABASECORRUPTED (25017)。

调用 SqlCeEngine 类的 Verify 方法会重新计算数据库文件中每个页面的校验和,并验证校验和是否匹配它们的预期值。如果该方法返回 true,则说明数据库文件没有损坏。如果该方法返回 false,则说明数据库文件已损坏,且应用程序应当调用 Repair 方法。

修复

如果数据库文件损坏,您可以尝试使用 SqlCeEngine 对象的 Repair(System.String,System.Data.SqlServerCe.RepairOption) 方法或本机 SQL Server Compact Edition Engine 对象的 Repair 方法来恢复该数据库文件。Repair 方法会扫描数据库并计算页面校验和。如果校验和与早先在将页写入数据库时计算出的校验和不匹配,该页便被视为已损坏。如果调用 Repair 方法时使用了 RepairOption.DeleteCorruptedRows 值,则将丢弃所有已损坏的页。如果损坏的页中包含数据库架构,这将导致重大数据损失。但是,使用 Repair 方法恢复的数据不会发生损坏。如果调用 Repair 方法时使用了 RepairOption.RecoverCorruptedRows 值,则数据库将尝试从损坏的数据页中读取数据。这样可以使更多的数据得到恢复。但是,使用此选项便无法保证恢复的数据没有逻辑损坏。

注意:
仅当 SQL Server Compact Edition 返回本机错误 SSCE_M_DATABASECORRUPTED (25017) 或者对 SqlCeEngine 对象的 Verify 方法的调用返回 false 时,才可以使用 Repair 方法。

自动刷新

如果数据库中的更改是由事务引起的,则在提交或中止事务前,这些更改一直保留在缓冲区池中。如果一个事务中止,则其更改将被丢弃。如果一个事务被提交,其更改便对其他用户和事务可见,但是这些更改可能无法立即写入数据库。如果发生了异常的程序终止(例如设备重置),则虽已提交但其更改尚未写入数据库的那些事务将被丢弃。

请注意,将事务写入数据库时总是按照它们的提交顺序进行。这意味着虽然某些事务可能会丢失,但数据库总是能够保持一致。例如,试考虑这样一种情况:某个应用程序提交了事务 A,然后提交了事务 B。如果该应用程序崩溃或者设备被重置,则数据库将处于下列三种状态之一:

  • 未更改
  • 由事务 A 做了更改
  • 由事务 A 和 B 做了更改。

按照事务的提交顺序将事务写入数据库减少了需要对数据库文件进行写操作的次数,从而改善了性能。如果在短时间内提交了许多较小的事务,则性能改善尤为显著。这种情况下会将所有的事务同时写入数据库文件中,而不会让各个事务分别引发一个数据库写操作。

缓冲区池中的挂起更改会按照 ADO .NET 中的 Flush Interval 连接字符串属性(OLE DB 中为 DPROP_SSCE_FLUSH_INTERVAL 属性)指定的时间间隔写入或刷新到数据库中。这些属性用于设置已提交的事务在刷新到磁盘之前等待的最大秒数。

注意:
对于在提交时必须保持到数据库中的事务,应用程序可以使用 CommitMode 枚举(OLE DB 中为 DBPROP_SSCE_TRANSACTION_COMMIT_MODE 属性)来覆盖提交时的默认刷新行为。通过使用这些属性,应用程序可以保证能够成功地保持发生在数据库中的所有事务。

备份/还原/删除

因为 SQL Server Compact Edition 是一个基于文件的数据库系统,所以您可以通过使用文件系统 API 来完成许多常见的数据库任务,例如备份、还原和删除数据库。

  • 若要备份一个数据库,请关闭到该数据库的所有连接,然后复制 .sdf 文件。
  • 若要还原一个数据库,请将 .sdf 文件复制回其正常工作位置。即使数据库被设置为用于复制,这些操作也同样可以执行。
  • 若要删除一个数据库,请删除 .sdf 数据库文件。

请参阅

其他资源

CompactDatabase 方法 (SQL Server Compact Edition)
Repair 方法 (SQL Server Compact Edition)

帮助和信息

获取 SQL Server Compact Edition 帮助