我知道使用 SERIAL
主键的 PostgreSQL 表会被 PostgreSQL 创建一个隐式索引、序列和约束。问题是当表重命名时如何重命名这些隐式对象。以下是我试图通过具体问题来解决这个问题的尝试。
例如给定下面的表:
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
value INTEGER
);
Postgres输出:
注意: 创建表将为序列列"foo.pkey"创建隐式序列"foo_pkey_seq"
注意: CREATE TABLE / PRIMARY KEY将为表"foo"创建隐式索引"foo_pkey"
查询成功返回,用时52毫秒。
pgAdmin III SQL面板显示了以下DDL脚本的表格(去除杂物):
CREATE TABLE foo (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE foo OWNER TO postgres;
现在重命名表格:
ALTER table foo RENAME TO bar;
查询成功返回,但结果为空,耗时17毫秒。
pgAdmin III:
CREATE TABLE bar (
pkey integer NOT NULL DEFAULT nextval('foo_pkey_seq'::regclass),
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
注意多出来的DEFAULT nextval('foo_pkey_seq'::regclass),
,这意味着重命名表格并不会同时重命名主键所用的序列,但现在我们有了明确的nextval()
。
现在重命名序列:
我想保持数据库命名的一致性,所以我尝试了:
ALTER SEQUENCE foo_pkey_seq RENAME TO bar_pkey_seq;
查询成功返回,但结果为空,用时17毫秒。
pgAdmin III:
CREATE TABLE bar (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
这个语句DEFAULT nextval('foo_pkey_seq'::regclass)
已经消失了。
问题
- 为什么会出现然后又消失了
DEFAULT nextval('foo_pkey_seq'::regclass)
这个语句? - 是否有一种方式可以重命名表并同时重命名主键序列?
- 在客户端连接到数据库时,重命名表和序列是否安全?是否存在并发问题?
- Postgres是如何知道要使用哪个序列的?内部是否使用数据库触发器?除了表和序列之外还需要重命名其他内容吗?
- 主键隐式创建的索引怎么办?应该重命名吗?如果是,应该如何操作?
- 上面提到的约束名仍然是
foo_pkey
。如何重命名约束?
<<tablename>>_pkey_seq
具有神奇的语法意义,并且Postgres知道使用此命名的序列作为表的主键序列,并省略明确列出它作为表的主键列的默认值。我实际上并不知道这一点,也没有任何证据支持它。如果这个问题到下班时间还没有答案,我会进一步调查。 - Mark Amery