You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby on Rails迁移中快速复制PostgreSQL大表至新表

问题描述

我正在开发基于Ruby on Rails与PostgreSQL数据库的项目,现有一张含百万级记录的大表old_X,需将其复制为新表new_X,要求两表的约束、默认值完全一致,且new_X的id字段需具备与原表相同的自增主键特性。我提出两种实现方案:

方案1:复制表后添加约束与索引

先复制原表数据至新表,为id字段创建序列,再添加非空约束、默认值等。具体代码如下:

# 复制原表数据到新表
execute <<-SQL.squish
  CREATE TABLE new_X AS TABLE old_X;
SQL

# 为id字段创建新序列
execute <<-SQL.squish
  CREATE SEQUENCE new_X_id_seq;
SQL

# 更新id列使用新序列作为默认值
execute <<-SQL.squish
  ALTER TABLE new_X
  ALTER COLUMN id SET DEFAULT nextval('new_X_id_seq');
SQL

# 将序列当前值设置为现有id的最大值
execute <<-SQL.squish
  SELECT setval('new_X_id_seq', (SELECT max(id) FROM new_X));
SQL

# 设置id为主键
execute <<-SQL.squish
  ALTER TABLE new_X
  ADD PRIMARY KEY (id);
SQL

创建表并导入数据后,需手动添加约束、默认值与索引,示例代码如下:

# 添加created_at和updated_at字段并设置非空约束与默认值
execute <<-SQL.squish
  ALTER TABLE new_X
  ADD COLUMN created_at timestamp without time zone NOT NULL DEFAULT NOW(),
  ADD COLUMN updated_at timestamp without time zone NOT NULL DEFAULT NOW();
SQL

添加索引的示例代码:

# 为is_Y字段创建索引
execute <<-SQL.squish      
CREATE INDEX CONCURRENTLY index_new_X_on_is_Y
  ON new_X (is_Y);
SQL

方案2:先创建完整结构的新表再插入数据

先创建包含所有字段、约束、默认值与索引的新表new_X,再将原表的百万级数据插入其中。

诉求

我更倾向于方案1,但因开发环境无百万级数据无法测试其表现,希望获取社区的相关经验、最佳实践与建议。


内容的提问来源于stack exchange,提问作者bahry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:32:04