为字段创建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