2

让我们假设我想将一个表规范化为 2 个表。例如。具有列 PhoneNumber1...PhoneNumber5 的表 Person 到表 Person 和 PhoneNumbers 中,具有从 Person 到 PhoneNumber 的外键约束并从 Person 表中删除 PhoneNumber1..PhoneNumber5 列。我想保留数据,即 PhoneNumber1..PhoneNumber5 应该最终作为一个记录,用于 PhoneNumber 表中的非空数据。任何模式比较工具都可以帮助实现这一目标吗?我检查了 SSDT,即使这个“功能”在他们的“路线图”上,它也不支持它

这只是我在日常生活中面临的一个简单场景,我们一直在使用手工编码的 SQL 来管理它。在更复杂的场景中,一组表可以更改为另一组表。在任何工具中是否有一种简单的方法来管理此类模式更改并同时成功管理数据映射?

4

2 回答 2

2

彼得建议的方法听起来很明智,例如

  1. 创建电话号码表
  2. 将数据从 People 表复制到 PhoneNumbers 表中
  3. 修改 People 表以删除 PhoneNumber1-5 列

假设复制数据所需的时间在您的停机时间内是可以接受的,可以作为一次“迁移”运行。

如果您有大量数据要复制并且需要避免停机,那么您可以添加一个抽象层来从两个位置读取数据,同时一点一点地复制数据。就像是:

  1. 创建电话号码表
  2. 部署代码以读取 People 或 PhoneNumbers,并仅写入新的 PhoneNumbers 表
  3. 在一段时间内将数据从 People 批量复制到 PhoneNumbers
  4. 删除从旧人物位置读取的代码
  5. 修改 People 表以删除 PhoneNumber1-5 列

您将部署更改 1 和 2,运行第 3 步,无论需要多长时间或在静默期,然后部署更改 4 和 5。

我发现Scott Ambler 和 Pramodkumar Sadalage所著的Refactoring Databases: Evolutionary Database Design这本书在计划这样的更改时非常有用。

在工具方面,如果您使用 SQL Server(或 Oracle),您可能有兴趣查看Red Gate SQL Source Control。这可以在单个部署中处理这种变化。全面披露——我确实为红门工作。

SQL Source Control 自动检测在开发数据库中所做的更改,并将这些更改链接到您现有的源代码控制系统。然后它可以生成将这些更改同步到另一个数据库所需的 SQL。有一个称为迁移的高级功能,它允许您将自动生成的更改的子集转换为手动 SQL 步骤,以用于更复杂的场景,例如数据迁移。您可以使用迁移来执行本文顶部描述的更改。

在您的开发数据库中,SQL 源代码控制会自动检测到新 PhoneNumbers 表的创建以及 People 表中 PhoneNumber1-5 的删除。您可以在工具中选择这两个更改并添加额外的 SQL 以在它们之间复制数据。它会将其保存为迁移脚本,当部署到另一个数据库(例如 QA/生产数据库)时, SQL Compare将识别并运行该脚本,以及它自动发现的任何其他更改。

于 2013-11-04T11:46:47.397 回答
0

这远远超出了我所知道的任何工具的重构。SSDT 可帮助您管理和控制架构,但您需要通过仔细规划和处理来处理此类更改,以避免数据丢失。

如果您正在创建一个全新的数据库来容纳新的结构/数据,那可能会有所不同。但是,当您尝试通过重命名/重新设计现有表来做到这一点时,您需要在计划中非常详细并小心处理。

可以通过 SSDT 做到这一点,但我会使用产品的多个版本来做到这一点: 1. 使用新结构创建新表。2. 将数据从原始数据复制到新数据 - 需要自定义脚本。3. 将原始表重构为“Name_Backup”之类的内容 4. 将新表重构为所需的名称。

您可能会在一个项目中执行步骤 1 和 2,也可能在项目的另一个版本中执行步骤 3 和 4。不管你怎么做,这种重构需要更多的计划和手动工作,而不是重命名列或添加/删除对象的更直接的重构。

于 2013-10-29T23:06:58.063 回答