2012-02-28 60 views
1

我们的数据库当前没有在任何表上定义主键。所有id列都只是唯一索引。我删除这些索引并用正确的主键替换它们。添加主键更改列类型

我的问题:在Postgres的8.4.7,特别是一个表改变从bigint数据类型到integer当我添加主键表。

我有如下表定义:

psql=# \d events 
             Table "public.events" 
     Column   |   Type   |      Modifiers      
-----------------------+--------------------------+----------------------------------------------------- 
id     | bigint     | not null default nextval('events_id_seq'::regclass) 
[more columns omitted] 

Indexes: 
    "events_id_unique_pk" UNIQUE, btree (id) 
Foreign-key constraints: 
    "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    "events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id) 
    "events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id) 
    "events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE 
    "events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id) 
    "events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id) 
    "events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id) 
Referenced by: 
    TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE 
Triggers: 
    event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate() 

这是发生了什么:

psql=# ALTER TABLE events ADD PRIMARY KEY (id); 
NOTICE: ALTER TABLE/ADD PRIMARY KEY will create implicit index "events_pkey" for table "events" 
ALTER TABLE 
psql=# \d events 
             Table "public.events" 
     Column   |   Type   |      Modifiers      
-----------------------+--------------------------+----------------------------------------------------- 
id     | integer     | not null default nextval('events_id_seq'::regclass) 
[more columns omitted] 

Indexes: 
    "events_pkey" PRIMARY KEY, btree (id) 
    "events_id_unique_pk" UNIQUE, btree (id) 
Foreign-key constraints: 
    "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    "events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id) 
    "events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id) 
    "events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE 
    "events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id) 
    "events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id) 
    "events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id) 
Referenced by: 
    TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE 
Triggers: 
    event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate() 

我考虑了几个解决方法,但我真的宁愿知道为什么它的发生。还有一些其他表也使用bigint,所以我不想只是解决方案。

这是用Liquibase编写的脚本,但它也直接发生在Postgres控制台中。


更新

其他两个点:

  • 我可以创建一个简单的表与bigint ID和id唯一索引,添加主键,列类型保持不变。
  • 执行时所有表都是空的。

它可能与约束有关吗?

+1

我发现很难相信添加主键约束可能会改变列的类型,但是让我们暂时假设它是一个错误。更新到最新的次要版本并再次测试。 – 2012-02-29 00:23:25

+0

@ MilenA.Radev这是控制台的文字输出,并且这三个命令是按顺序输入的。无论如何,我们正在从Postgres 8.4升级到9.1。我可以在几天内对此进行测试。 – Brandan 2012-02-29 03:21:22

回答

1

即使在第一次发生与证人重复多次之后,我仍无法在第二天再次复制此内容。我正在把它写成gremlins。

1

这很有趣。我不能在9.1.0版中复制它(是的,我应该升级!)。但是我不清楚原始表格和序列是如何创建的。

本页面似乎暗示SERIAL和INTEGER之间的类型相似的自动变化:http://grover.open2space.com/content/migrate-data-postgresql-and-maintain-existing-primary-key

难道是像创建一个使用串行而不是BIGSERIAL表,然后强迫为bigint类型?序列和主键操作之间的某些内容可能会重置它。