postgresql - 在 Postgresql 中使用表重命名交换表内容时会出现什么问题?
问题描述
我需要自动更改 Postgresql 表中的大量行。我正在使用这样的技术:将数据添加到临时表,然后通过将 original 重命名为 not_matter_name 并将 temp 重命名为原始名称来交换表。此处描述了该技术。
但是这种方法被打破了。例如,我发现视图不会更新指向新表的指针,即使在名称交换后仍指向旧表。我找到的唯一解决方案是重新创建视图,这有点糟糕。
除了视图问题之外,这种技术还会出现什么问题?
我总体上做错了吗?有没有更好的快速交换表的解决方案,不会对其他 Postgresql 实体造成这样的副作用?
代码如下所示:
CREATE TABLE _temp_with_updated_data (like original_name including all);
--...MANY INSERTS TO _temp_with_updated_data
begin;
alter table original_name rename to ___doesnt_matter;
alter table _temp_with_updated_data rename to original_name;
alter table ___doesnt_matter to _temp_with_updated_data;
truncate table _temp_with_updated_data;
commit;
解决方案
另一个问题(除了视图)是外键,如果你有外键的话。当它被重命名时,它们也将遵循原始表。函数没有问题,因为它们在执行时解析表名,而不是在创建时解析。
如果您不喜欢重新创建视图,您可以使用从空基表继承的方法,并将视图指向该表。然后你不会继承旧的并继承新的。就我个人而言,我发现这种治疗方法比疾病更糟糕,只是重新创造了这些观点。您可以从 获取视图定义pg_dump -s
,如果您还没有将它们隐藏在某个地方,但您需要自己整理出您需要哪些定义。
另一个问题可能只是性能问题,批量插入已索引的表可能会很慢。您可能希望使用 INCLUDING ALL EXCLUDING INDEXES 创建,然后在填充索引后构建索引。唉,PostgreSQL 并没有让第二部分变得容易。没有什么能像假设的 ALTER TABLE foo2 INCLUDE INDEXES LIKE foo1 这样您可以在事后运行(但同样pg_dump -s
可以在这里提供帮助,以获取创建索引语句的列表)。但是,如果当前的性能不打扰您,那么首先不要排除索引,您以后就不需要构建它们。
推荐阅读
- java - 尝试从 Cucumber 1.0.2 info.cukes 升级到 5.6 io.cucumber,无法识别步骤定义
- odoo-12 - odoo12如何不间断地显示成功消息
- service-worker - 按需保存 URL 以进行缓存
- java - 关于将 mysql 连接器与 intellij 连接的问题
- mysql - 为什么我不能在 MYsql 上删除表?
- r - 在 R 中自动生成代码以创建数据框
- python - 是否有一个简单的 python 3 命令可以在多列上复制 matlab 的 interp1 命令?
- c# - 数据库 sqlite 中的项目未更新 (Xamarin.Forms)
- html - 将页脚推到 flexbox 底部
- python-3.x - 一段代码的语法错误被接受为 str.join 的参数