创建应用程序数据的快照-最佳实践

本文关键字:最佳 快照 应用程序 数据 创建 | 更新日期: 2023-09-27 18:17:37

我们有一个使用。net FW 4.0用c#开发的文本处理应用程序,其中管理员可以定义各种设置。所有这些"设置"数据驻留在大约50个带有外键关系和Identity主键的表中(我认为这将使它变得棘手)。整个数据库不超过100K条记录,平均每个表大约有6个短列。本系统基于MS SQL 2008 R2 Express数据库。

我们需要创建所有这些数据的快照,以便系统管理员在搞砸某些事情时可以回滚到其中一个快照。我们只需要保留最后5个快照。快照的创建必须从应用程序GUI开始,因此如果需要,必须回滚到任何快照(不允许使用SSMS,因为拒绝直接访问DB)。系统仍处于开发阶段(我们真的完成了吗?),这意味着需要多次添加新的表和列。因此,我们需要一种能够自动处理更改的健壮方法(在插入/更改列之后挖掘代码是我们希望避免的,除非没有其他方法)。最好的方法是告诉用户"我想创建一个名称以‘Admin’开头的所有表的快照"。显然,这是一个相当密集的数据库任务,但由于它只会在紧急情况下使用,这是我不介意的。我也不介意发生表锁,因为在快照的创建或回滚过程中,没有人会尝试使用这些表。

问题可分为两部分:

    创建快照
  1. 回滚到快照

关于问题1。我们可能有两个选择:

  1. 将数据导出为XML(文件或数据库列)
  2. 将SQL中的数据复制到相同或不同的表中(例如再次创建与原始表相同名称的表结构,并以"Backup"为前缀)。

关于问题2。我看到的最大问题是如何将所有数据重新导入到使用IDENTITY列进行PK生成的外键相关表中。我需要从所有受影响的表中删除所有数据,然后重新导入所有内容,同时暂时放松FK约束并关闭Identity生成。一旦数据加载,我应该检查FK约束是否仍然OK。

或者我应该找到一种逻辑方式来加载表,以便在加载时约束检查可以保持在适当的位置(因为我们没有无法管理的表数量,这可能是一个可行的解决方案)。当然,我需要在一个事务中完成所有的删除和重新加载,原因很明显。

我怀疑可能没有纯基于SQL的解决方案,尽管SQL CLR可能有助于避免将数据移出SQL Server。

有没有人和我们面临同样的问题?也许有人成功地解决了这个问题?

我不期待一步一步的指导。任何关于从哪里开始,采取哪条路线(导出到RAW XML或在DB中保留快照或两者)的帮助,利/弊将非常有帮助。

感谢您的帮助和您的时间。

丹尼尔

创建应用程序数据的快照-最佳实践

我们没有这个确切的问题,但是我们有一个非常类似的问题,我们向客户提供了一组基线配置数据(相当复杂,主要是身份pk),当我们提供新版本时需要更新。

对于您的情况,我们的机制可能有些过头了,但我确信其中有一部分是适用的。

基本的方法是:

首先,我们执行一个脚本,删除所有FK约束,并将那些当前为NOT NULL的FK列的可空性更改为NULL。该脚本还删除了所有触发器,以确保在其中实现的任何逻辑约束都不会被执行。

接下来,执行数据导入,在更新表之前将identity_insert设置为off,然后在更新表中的数据后将其设置为on。

接下来,我们执行一个脚本,该脚本根据外键检查新添加项的数据完整性。在我们的例子中,我们知道没有相应父记录的项可以安全地删除,但是您可以选择采用不同的方法(报告错误并让某人手动处理问题)。

最后,一旦我们验证了数据,我们执行另一个脚本,恢复可空性,添加fk,并重新安装触发器。

如果你有预算,我会强烈建议你看看Red Gate提供的工具,特别是SQL Packager和SQL Data Compare(我怀疑可能还有其他工具,我们只是没有任何经验)。这些工具对于成功实施我们的战略至关重要。

我们通过RedGate的SQL Packager生成的SQL脚本提供基线配置。

因为我们的最终用户可以在更新之间修改数据库,这将导致他们数据库中的标识值与我们的数据库中的标识值不同,所以我们实际上将基线主键和外键存储在每个记录的单独字段中。

当我们更新客户数据库时,我们需要将新记录链接到已知的配置信息,我们可以使用基线字段来找出数据库特定的fk应该是什么。

换句话说,无论数据库中的其他数据被修改了什么,总是有一组已知的配置记录的字段id,我们可以使用它将记录链接在一起。

例如,如果我将表1链接到表2,表1将有一个基线PK,表2将有一个基线PK和一个包含表1基线PK的基线FKey。当我们更新记录时,如果我们添加一个新的表2记录,我们所要做的就是找到具有指定基线PK的表1记录,然后用表1中的实际PK更新表2中的实际FKey。

按日期范围进行版本控制是企业应用程序中记录的一种常用方法。例如,我们有一个商业实体(us)或公司(uk)的表,并在另一个表中保留当前的正式名称,如下所示:

CompanyID    Name            ValidFrom     ValidTo
12           Business Lld    2000-01-01    2008-09-23
12           Business Inc    2008-09-23    NULL

最后一条记录中的null表示这是当前记录。您可以使用上述逻辑并可能添加更多列以获得更多控制。这样就不会有重复,您可以将历史记录保留到任何级别,并轻松地跨表同步当前值。最后,表演将是伟大的。