安全地使用序列主键列重命名表

22 浏览
0 Comments

安全地使用序列主键列重命名表

我知道使用SERIAL主键的PostgreSQL表会被PostgreSQL创建一个隐式索引、序列和约束。问题是如何在重命名表时重新命名这些隐式对象。下面是我试图解决这个问题并提出具体问题的尝试。

给定一个表如下:

CREATE TABLE foo (
    pkey SERIAL PRIMARY KEY,
    value INTEGER
);

Postgres输出:

注意:CREATE TABLE将为序列列"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),消失了。

问题

  1. DEFAULT nextval('foo_pkey_seq'::regclass)语句为什么会出现和消失?
  2. 是否有一种方法可以同时重命名表和主键序列?
  3. 在连接到数据库的客户端连接时重命名表和序列是否安全?是否存在并发问题?
  4. Postgres如何知道使用哪个序列?是否在内部使用数据库触发器?是否还有其他需要重命名的对象除了表和序列?
  5. 通过主键创建的隐式索引如何处理?是否应该重命名?如果是,如何操作?
  6. 上面的约束名称如何处理?它仍然是foo_pkey。如何重命名约束?
0
0 Comments

问题的原因是,在PostgreSQL中使用伪数据类型serial来创建主键列时,系统实际上会自动创建一个序列和一个整数类型的列。而当我们尝试重命名这些表时,系统对序列的重命名并没有提供自动的支持。

解决方法是使用ALTER SEQUENCE语句来重命名序列,同时使用ALTER TABLE ... RENAME CONSTRAINT语句来重命名主键约束的隐式索引。此外,还可以使用ALTER INDEX语句来重命名与表名相关的索引。

需要注意的是,重命名操作可能会受到并发事务的影响。如果有其他事务持有相关对象的锁定,重命名操作将被阻塞,直到这些事务提交或回滚。

此外,文章还提到了关于系统目录和OID(对象标识符)的内容。系统目录存储了数据库架构的信息,如果不了解具体操作,最好不要直接操作系统目录表。而OID是一种用于表示对象的唯一标识符的数据类型,可以通过类型转换来快速获取OID对应的名称。

最后,文章还提到了ALTER TABLE ... RENAME CONSTRAINT语句需要PostgreSQL 9.2及以上版本支持的问题。

当在PostgreSQL中使用serial来创建主键列时,我们需要手动重命名相关的序列和索引才能完成表的重命名操作。

0