在测试(not生产)数据库上运行此ActiveRecord迁移时,db/structure.sql个数据库中会出现较大的变化.这是可重现的.更改如下:

  • 基于迁移代码的少量预期更改(根据需要).
  • 大量与迁移代码无关的意外更改(不需要).这是迁移中的SQL代码中提到的not个.这些重新排列的项与迁移中的SQL代码中的项相关联(例如,通过相关性)not.

What causes these large unrelated differences, and how to prevent them?

这些问题是否与生产数据库服务器上的PostgreSQL版本与在测试数据库上执行迁移的计算机上的PostgreSQL版本不匹配有关?

这些不相关的更改会降低git diff输出much的用处.在下面这个极小的示例中,只重新排列了几个表.但在现实生活中的迁移代码中,它改变了几十个表、视图和matview的顺序.

class FixFooBarBaz < ActiveRecord::Migration[5.2]

  def up
    sql = <<~SQL
                  DROP VIEW master_foo;
                  DROP VIEW IF EXISTS bar1;
                  CREATE OR REPLACE VIEW bar1 AS
                  SELECT * FROM baz1
                  UNION ALL
                  SELECT * FROM baz2;
                  CREATE OR REPLACE VIEW master_foo AS
                  SELECT
                      *,
                      'bar1' AS bar_type
                  FROM
                      bar1
                  UNION ALL
                  ...
    SQL

    execute sql
  end

  def down
    sql = <<~SQL
                  DROP VIEW IF EXISTS master_foo;
                  DROP VIEW IF EXISTS bar1;
                  ...
    SQL

    execute sql
  end
end 

使用的硬件/软件:

执行迁移的计算机:

MacBookPro, Apple M1 Max, macOS Sonoma 14.2.1
ruby 2.7.3p183 (2021-04-05 revision 6847ee089d) [arm64-darwin21]
15.3 psql (PostgreSQL) 15.3 (Homebrew)

生产数据库服务器:

psql (14.9 (Homebrew), server 13.3 (Ubuntu 13.3-1.pgdg20.04+1))

推荐答案

不,这与不同的数据库版本无关,它更多地取决于不同用户运行迁移的顺序.如果您让您的所有团队吹走他们的数据库,并从公共转储重新加载它们,那么它们都将产生相同的输出……直到有人以不同的顺序运行迁移(这显然会在多个用户创建新迁移时发生).

不幸的是,没有简单/好的方法来解决这个问题.

回复来自OP的 comments 的更新:

每个人在其笔记本电脑上运行的PostgreSQL版本略有不同

是的,正如我所说的,在我的经验中,这与PG版本没有任何关系(也许大的版本差异会产生不同,我的团队从来没有大的差异,所以无可奉告).

许多年,数百次迁移,跨越一小群开发人员[...]db/structure.sql年的变化总是与相应的迁徙保持一致

我有过同样的经历,一旦事情开始变化/冲突,似乎就再也不会回到原来的样子了.我花了很多时间(比如一周的专心时间)来研究它,但从来没有找到任何启发式的东西来解释为什么事情开始了,也没有发现如何让事情回到原来的样子.我见过团队中只有一个成员经历了"自创建的迁移在自己的 struct 中触发它"的情况,即.其他成员仍然可以创建迁移,并且 struct /架构会进行明智的更新.但到了这个时候,通常是多个成员都经历了同样的事情,很明显,一旦一个成员经历了这种情况,当其他成员退出共享回购时,他们就会开始看到冲突/巨大的变化.

在pg中似乎有一些内在的东西,在达到一定的模式复杂性/db对象大小后,它必须开始以某种方式存储新对象,当它们更改时,转储会发生显著变化.我从来没有在一个小数据库里见过它.

Sql相关问答推荐

使用SQL/R循环查找邻居

为什么Postgrs Planner会在输出部分中显示我在查询中不使用的列?'""

Postgres JSONB对象筛选

如何在PostgreSQL中对第1,1,1,1,2,2,2,2行进行编号

返回UPSERT中的旧行值

如果多行科目有一行在指定的日期范围内,如何 Select 该科目在该日期之前的所有行?

如何从查询中的三个或更多个表中添加另一个相同的列?

使用递归CTE在BigQuery中获取文件路径

删除行而不使数据库超载

对于小数据集,EF / SQL 语句花费的时间太长

在 Oracle 21c 中透视文本值

PostgreSQL - 递归地聚合来自不同列的属性

PostgreSQL - 从同一张表中获取值

Postgresql 需要一个查询,为我提供所有没有具有特定状态值的子元素的父母

SQLite 中的过滤运行总和视图

如何在 PL/SQL 中区分返回的 XML 值?

从每行中排除最大元素

运算符不存在:integer = bigint[]

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

如果当前日期是一周中的某一天,则从另一天提取结果