彼得建议的方法听起来很明智,例如
- 创建电话号码表
- 将数据从 People 表复制到 PhoneNumbers 表中
- 修改 People 表以删除 PhoneNumber1-5 列
假设复制数据所需的时间在您的停机时间内是可以接受的,可以作为一次“迁移”运行。
如果您有大量数据要复制并且需要避免停机,那么您可以添加一个抽象层来从两个位置读取数据,同时一点一点地复制数据。就像是:
- 创建电话号码表
- 部署代码以读取 People 或 PhoneNumbers,并仅写入新的 PhoneNumbers 表
- 在一段时间内将数据从 People 批量复制到 PhoneNumbers
- 删除从旧人物位置读取的代码
- 修改 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将识别并运行该脚本,以及它自动发现的任何其他更改。