为字段创建PostgreSQL序列(不是记录的ID)

我正在开发Ruby on Rails应用程序。 我们正在使用PostgreSQL数据库。

有一个名为scores的表,其中包含以下列:

 Column | Type --------------+----------------------- id | integer value | double precision ran_at | timestamp active | boolean build_id | bigint metric_id | integer platform_id | integer mode_id | integer machine_id | integer higher_better | boolean job_id | integer variation_id | integer step | character varying(255) 

我需要在job_id添加一个序列 (注意:没有job模型)。

如何创建此序列?

使用CREATE SEQUENCE

 CREATE SEQUENCE scores_job_id_seq; -- = default name for plain a serial 

然后在scores.job_id添加一个默认列:

 ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('scores_job_id_seq'); 

如果要将序列绑定到列(因此在删除列时将其删除),还要运行:

 ALTER SEQUENCE scores_job_id_seq OWNED BY scores.job_id; 

所有这些都可以替换为使用伪数据类型serial for column job_id开头:

  • 安全,干净地重命名在Postgres中使用串行主键列的表?

如果您的表已有行,您可能需要将SEQUENCE设置为下一个最高值,并在表中填写缺少的序列值:

 SELECT setval('scores_job_id_seq', COALESCE(max(job_id), 0)) FROM scores; 

可选:

 UPDATE scores SET job_id = nextval('scores_job_id_seq') WHERE job_id IS NULL; 
  • 如何有效地检查PostgreSQL中已使用和未使用的值的序列
  • Postgres手动改变序列
  • 如何在postgres不同步时重置postgres的主键序列?

唯一剩下的区别是, serial列也设置为NOT NULL 。 您可能也可能不想要这样:

 ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL; 

但是不能只改变现有integer的类型:

 ALTER TABLE scores ALTER job_id TYPE serial; 

serial不是实际的数据类型。 它只是CREATE TABLE一个符号便利function。

所以我想出了如何使用Ruby on Rails上的ActiveRecord迁移来实现这一点。 我基本上从这个页面使用了Erwin的命令和帮助,并将它们放在迁移文件中。 这些是步骤:

1.在终端中,键入:

 rails g migration CreateJobIdSequence rails g migration AddJobIdSequenceToScores 

2.编辑迁移文件,如下所示:

20140709181616_create_job_id_sequence.rb

 class CreateJobIdSequence < ActiveRecord::Migration def up execute <<-SQL CREATE SEQUENCE job_id_seq; SQL end def down execute <<-SQL DROP SEQUENCE job_id_seq; SQL end end 

20140709182313_add_job_id_sequence_to_scores.rb

 class AddJobIdSequenceToScores < ActiveRecord::Migration def up execute <<-SQL ALTER SEQUENCE job_id_seq OWNED BY scores.job_id; ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('job_id_seq'); SQL end def down execute <<-SQL ALTER SEQUENCE job_id_seq OWNED BY NONE; ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL; SQL end end 

3.迁移数据库。 在终端类型中:

 rake db:migrate