我们的数据库目前没有在任何表上定义主键。所有的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控制台中。
更新
另外两点:
- 我可以在
id
上创建一个具有bigint
id和唯一索引的简单表,添加主键,列类型保持不变 - 执行时所有表都为空
这可能与限制有关吗?
这很有趣。我无法用9.1.0版本复制它(是的,我也应该升级!)。但我不知道最初的表和序列是如何创建的。
本页似乎暗示了SERIAL和INTEGER之间类型的类似自动更改:http://grover.open2space.com/content/migrate-data-postgresql-and-maintain-existing-primary-key
这可能是使用SERIAL而不是BIGSERIAL创建表,然后强制类型为BIGINT吗?序列和主键操作之间的某些东西可能已经重置了它。
即使在第一次与目击者多次复制后,我第二天也无法复制。我把它归结为小妖精。