在已经存在数据的项目中工作,项目需求的变化并不罕见,并迫使您更改表结构。
我的问题是在部署期间如何将数据从旧表架构移动到新表架构,同时以最小的停机时间应用迁移?停机时间是指您的应用无法访问的时间,从而导致错误。
假设您有一个负责迁移的数据库迁移任务(如果迁移失败,则还原MySQL语句)。
我不是在谈论重命名数据库列,因为在这种情况下,数据库只需重命名该列而不会丢失任何数据。
原始表post
,有200万个条目:
| name | slug | content | tags |
tags
是text
列,其中标记以逗号分隔。
为了使事情更清楚,您决定tags
需要是一个单独的表,并创建一个postTag
表,如下所示:
| id | name |
| postId | tagId | # both are foreign keys
我知道场景数据库结构从一开始就是糟糕的设计,我只是把它想象成一个虚构的场景来说明我的观点。
可能的解决方案是,复制和重命名旧表,并通过某种钩子执行脚本来处理数据迁移吗?我认为这不会起作用,特别是如果该表中涉及外键。当然你可以暂时禁用外键检查,但听起来不像是一个可靠的解决方案。
此外,由于我们有200万个条目,脚本需要花费大量时间,这意味着我们的停机时间会延长。
如果我们使用完全独立的数据库怎么办?最初,我们将复制生产数据库(或者只是在可能的情况下复制它),一旦复制100%同步,禁用复制,并在第二个数据库上运行我们的迁移脚本。在部署期间更改数据库环境变量以指向我们的第二个数据库,然后删除第一个数据库。
我可以想到这种方法的一个可能问题是:这是 LIVE 网站!在数据库#2上的迁移完成之前,数据库#1上添加的新数据会发生什么?我们可能会丢失重要数据。当然,我们可以简单地询问我们的作者,不要在那时添加任何帖子,但是如果它是一个论坛用户贡献内容怎么办?我们必须关闭一些功能才能做到这一点,这意味着更多的“停机时间”。
我非常感谢有关此问题的任何见解。
P.S。:我之前做过类似的任务:它将数据从遗留应用程序移动到新应用程序。新的应用程序不是实时的,因此迁移更容易。