使用视图的Postgres中的零步跨度架构迁移

2021-06-17 03:15:27

架构迁移很棘手,特别是当计划的停机时间不是一个选项时。需要仔细设计更改以保持向后兼容,以便同时使用新的和旧模式。它们还必须设计成不会干扰任何其他查询,例如通过锁定表。已经写过了如何正确的权利,但我没有看到的一个图案经常使用视图。

该想法是封装数据库中的数据。客户端不会查询存储数据的实际表,而是将直接映射到底层表的视图查询。每个版本的模式都有一组永远不会改变的视图。这样,我们可以对底层表执行更改,同时为客户端维护稳定的架构。

这种技术不常见的原因可能只是它是愚蠢的,但这不应该阻止我们探索它!

让我们用一个粗略的简单迁移来测试这个模式:重命名一列。假设我们有一个名为ID的非唯一列,我们要重命名为User_ID。在没有停机时间的推荐方式实现这一目标是:

PHEW,这是一个很好的过程!如何查看和封装如何帮助我们?我们首先设置我们的表并插入一些数据。请记住,此表将永远不会直接查询。

创建表用户(ID串行主键,电子邮件文本,名称文本);插入用户(电子邮件,姓名)值(' [email protected]',' jerry seinfeld'),(' [email protected]' ;,' George Costanza');

现在我们需要一些观点,以便我们实际上可以检索这些数据。一个好的诀窍是使用Postgres模式来掌握我们的观点。我们的架构的每个版本都将获得自己的Postgres架构,并且它们将为每个底层表包含一个视图。如果我们调用我们的起始架构“A”,我们可以将其设置为:

创建架构a;创建视图a。用户作为选择ID,电子邮件,公共名称。用户 - Public是创建表的默认模式

现在,所有客户都必须做的是在查询期间指定它们想要的模式的哪个版本。要保持应用程序代码迁移不可知求,我们可以在连接时设置搜索路径:

将search_path设置为a; - 用户现在将参考A.Users选择ID,电子邮件,用户名称; - 结果: - + ---- + -------------------------------- ----- + - | ID |电子邮件|名称| - + ---- + ----------------------------------- - + - | 1 | [email protected] |杰里·塞内德| - | 2 | [email protected] |乔治科斯坦扎| - + ---- + ----------------------------------- - +

现在为隆重的结局,我们如何重命名ID列?如果我们执行常规重命名,Postgres将更新现有A.Users视图以引用新名称,同时仍称为ID ID,保持更改向后兼容。我们还需要介绍我们使用新user_id名称的新版本的模式,让我们称之为“B”:

改变桌子公众。用户将列ID重命名为USER_ID;创建架构b;创建视图b。用户作为Select User_ID,电子邮件,来自Public的名称。用户;

重命名完成了!没有停机,没有额外的列,没有触发器,没有回填。只是良好的旧封装。

- 旧客户端仍然可以访问旧列名称设置搜索_path;选择ID,电子邮件,用户名称; - 结果: - + ---- + -------------------------------- ----- + - | ID |电子邮件|名称| - + ---- + ----------------------------------- - + - | 1 | [email protected] |杰里·塞内德| - | 2 | [email protected] |乔治科斯坦扎| - + ---- + ----------------------------------- - + - 新客户端只需将他们的搜索路径集Search_Path更新到B;选择user_id,电子邮件,来自用户的名称; - 结果: - + --------- + -------------------------- ---------- + - | user_id |电子邮件|名称| - + --------- + ------------------------------- ------ + - | 1 | [email protected] |杰里·塞内德| - | 2 | [email protected] |乔治科斯坦扎| - + --------- + ------------------------------- ------ +

重命名一列允许是最简单的迁移和抛出外来钥匙和索引等的东西,将永远复杂化。 希望这种观点封装技术在更复杂的情景中会有所帮助。 设置一个清晰的版本化的界面,可以通过不断迁移迁移的实现详细信息,帮助保持应用程序代码更简单。 我目前正在处理一个工具,旨在使开发人员轻松地制作零步开发的架构迁移。 如果你认为这听起来很有趣,那么请给我发电子邮件! 如果您想讨论这篇文章或者只是聊天,那么也可以随意伸出援手。