假设我想将一个表标准化为 2 个表。例如。将具有 PhoneNumber1...PhoneNumber5 列的表 Person 插入到表 Person 和 PhoneNumbers 中,并使用从 Person 到 PhoneNumber 的外键约束,并从 Person 表中删除 PhoneNumber1..PhoneNumber5 列。我想保留数据,即 PhoneNumber1..PhoneNumber5 应最终作为 PhoneNumber 表中非空数据的一条记录。任何模式比较工具可以帮助实现这一目标吗?我检查了 SSDT,它不支持它,即使这个“功能”在他们的“路线图”上
这只是我在日常生活中遇到的一个简单场景,我们一直在使用手动编码的 SQL 来管理它。在更复杂的情况下,一组表可以更改为另一组表。在任何工具中是否有一种简单的方法来管理此类架构更改并同时成功管理数据映射?
最佳答案
Peter 建议的方法听起来很明智,例如
- 创建 PhoneNumbers 表
- 将数据从 People 表复制到 PhoneNumbers 表中
- 修改 People 表以删除 PhoneNumber1-5 列
前提是复制数据所需的时间在您可以作为一次“迁移”运行的停机时间内可以接受。
如果您有大量数据需要复制并且需要避免停机,那么您可以添加一个抽象层来从两个位置读取数据,同时一点一点地复制数据。像这样的东西:
- 创建 PhoneNumbers 表
- 部署代码以从 People 或 PhoneNumbers 中读取数据,并仅写入新的 PhoneNumbers 表
- 在一段时间内批量将数据从 People 复制到 PhoneNumbers
- 删除从旧用户位置读取的代码
- 修改 People 表以删除 PhoneNumber1-5 列
您将部署更改 1 和 2,无论需要多长时间或在安静时期运行步骤 3,然后部署更改 4 和 5。
我找到了这本书Refactoring Databases: Evolutionary Database Design作者:Scott Ambler 和 Pramodkumar Sadalage 在规划此类变更时非常有帮助。
就工具而言,如果您使用 SQL Server(或 Oracle),您可能有兴趣查看 Red Gate SQL Source Control 。这可以在单个部署中处理此更改。全面披露 - 我确实为 Red Gate 工作。
SQL 源代码管理自动检测开发数据库中所做的更改,并将这些更改链接到您现有的源代码控制系统。然后,它可以生成将这些更改同步到另一个数据库所需的 SQL。有一个名为“迁移”的高级功能,它允许您将自动生成的更改的子集转换为手动 SQL 步骤,以适应更复杂的场景(例如此数据迁移)。您可以使用迁移来执行本文顶部描述的更改。
在您的开发数据库中,SQL 源代码管理会自动检测到新 PhoneNumbers 表的创建以及 People 表中 PhoneNumber1-5 的删除。您可以在工具中选择这两个更改,并添加额外的 SQL 以在它们之间复制数据。它将保存为迁移脚本,SQL Compare在部署到另一个数据库(例如 QA/生产数据库)时会识别并运行,以及它自动发现的任何其他更改。
关于compare - 使用模式比较工具处理模式重构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19647918/