【问题标题】:Handling schema refactoring using schema compare tools使用模式比较工具处理模式重构
【发布时间】:2013-11-04 19:46:47
【问题描述】:

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

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

【问题讨论】:

    标签: compare schema sql-server-data-tools


    【解决方案1】:

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

    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。这可以在单个部署中处理这种变化。全面披露 - 我确实为 Red Gate 工作。

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 感谢您的回答。我希望有一个工具可以让我 1) 取消选择我不想自动同步的表和 2) 针对这些表在自定义 SQL 语句中编写代码以将它们同步到新的表集。然后,该工具将负责运行自定义 SQL 语句,以及它自己为数据库中的其余表自动生成的语句。这样我就不必知道该工具在内部是如何工作的,也不会遇到任何性能问题,如果我必须仔细规划并执行一系列步骤的更改
      • 我不知道有什么可以照顾所有幕后人员,并且以不会导致性能问题的方式进行。这是重构数据库设计成本的很大一部分。您需要知道数据的去向并确保它到达那里。我不知道我是否真的相信一个工具可以为我做到这一点,因为出错的代价可能是数据完全丢失。我很确定您需要手动处理这些情况,并尝试在将来尽可能地防止它们。
      猜你喜欢
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-26
      • 2020-12-22
      • 1970-01-01
      相关资源
      最近更新 更多