Dav*_*vid 3 postgresql migration view
我在我们的数据库中有一个非常重要的表,它被一系列应用程序使用,它附有规则、触发器和您可以想象的所有依赖项。现在我想修改表而不会对依赖项造成任何问题。我以前成功地执行了以下操作,但在一个不太复杂的情况下:
alter table reconciliations rename to matches;
create view reconciliations as select * from matches;
Run Code Online (Sandbox Code Playgroud)
这实现的是我现在可以修改新的“匹配”表,例如添加一列或多行,这些列或行不需要在“对帐”视图中显示(通过添加 where 子句来过滤它们)。
我使用的是 Postgres 9.5,因此视图可以自动更新。初步测试表明,这没有直接问题,所以我问这个问题是为了知道我应该寻找什么样的问题。性能不是大问题。
如果您在生产中这样做,请注意准备好的语句。那些已经被解析、重写(并缓存了查询计划)。效果会一直持续到准备好的语句被释放(这可能需要很长时间)。
检查准备好的语句(仅限同一会话!):
TABLE pg_prepared_statements;
Run Code Online (Sandbox Code Playgroud)
该效果还扩展到 plpgsql 函数,这些函数在内部处理 SQL 命令(如准备好的语句)。
通常,在对涉及的对象进行任何更改后,必须重新规划准备好的语句。但是你的行为绕过了这个安全机制。
此外,大多数查询将继续工作。但不是所有的。
CREATE TEMP TABLE foo (id int);
INSERT INTO foo VALUES (4);
PREPARE x AS SELECT foo FROM foo WHERE id > $1; -- uses row type
Run Code Online (Sandbox Code Playgroud)
这有效:
ALTER TABLE foo ADD COLUMN t text;
EXECUTE x(3); -- automatically re-planned
Run Code Online (Sandbox Code Playgroud)
但这不是:
ALTER TABLE foo RENAME TO foo1;
CREATE VIEW foo AS TABLE foo1;
ALTER TABLE foo1 ADD COLUMN t text;
EXECUTE x(3); -- not re-planned!
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)ERROR: cached plan must not change result type
尽管预处理语句的主要目的是避免语句的重复解析分析和规划,但是只要语句中使用的数据库对象发生了定义(DDL)更改,PostgreSQL 就会在使用之前强制重新分析和重新规划该语句因为之前使用了准备好的语句。此外,如果
search_path从一次使用到下一次使用的值发生变化,语句将使用新的search_path. (后一种行为从 PostgreSQL 9.3 开始是新的。)这些规则使用准备好的语句在语义上几乎等同于一遍又一遍地重新提交相同的查询文本,但是如果没有对象定义被更改,则具有性能优势,特别是如果最佳计划在不同用途中保持不变。语义等价不完美的一个例子是,如果语句以不合格的名称引用一个表,然后在前面出现的模式中创建一个同名的新表,则search_path不会自动重新解析将发生,因为语句中使用的对象没有改变。但是,如果某些其他更改强制重新解析,则在后续使用中将引用新表。
以上是“语义等价不完美”的另一个例子。
| 归档时间: |
|
| 查看次数: |
1674 次 |
| 最近记录: |