采用串行主键列安全重命名表(Safely rename tables using serial pr

2019-07-19 03:12发布

我知道,使用一个PostgreSQL的表SERIAL PostgreSQL所创建的主键结了一个隐含的指数,序列和约束。 现在的问题是如何在重命名了表重命名这些隐含对象。 下面是我在末尾的具体问题搞清楚了这一点尝试。

给定一个表,如:

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

Postgres的输出:

注意:CREATE TABLE将创建隐序列“foo_pkey_seq”串行列“foo.pkey”
注意:CREATE TABLE / PRIMARY KEY将创建隐式索引 “foo_pkey” 对表 “富”
查询没有结果在52毫秒成功返回。

pgAdmin的III SQL窗格显示表(decluttered)以下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 。 约束如何改名?

Answer 1:

serial不是实际的数据类型。 该手册指出 :

数据类型smallserialserialbigserial不是真正的类型,而仅仅是一个符号上的便利为创建的唯一标识符列

伪数据类型解决做了这一切:

  • 创建一个名为序列tablename_colname_seq

  • 创建与类型列integer (或int2 / int8分别为smallserial / bigserial

  • 使列NOT NULL DEFAULT nextval('tablename_colname_seq')

  • 使自己列的顺序,以便它能够与它会自动下降

系统知道你是否做了这一切通过手工或伪数据类型的方式serial 。 对列出的特征,并且如果所有的pgAdmin检查被满足时,逆向工程DDL脚本与匹配简化serial类型。 如果不满足的特征之一,这种简化不会发生。 这是pgAdmin的东西呢。 对于底层的目录表是完全一样的。 没有serial类型等。

有没有办法来自动重命名国有序列。 您可以运行:

ALTER SEQUENCE ... RENAME TO ...

像你这样。 该系统本身并不关心名字 。 列DEFAULT店的OID'foo_pkey_seq'::regclass ),您可以更改序列的名称,而不打破了-该OID保持不变。 这同样适用于外键和数据库内类似提法。

主键的隐式索引被绑定到PK的约束,如果更改表的名称将不会改变的名称。 在Postgres的9.2或更高版本可以使用

ALTER TABLE ... RENAME CONSTRAINT ..

纠正这一点。

此外,还可以在参考表名称命名的索引。 类似的方法 :

ALTER INDEX .. RENAME TO  ..

你可以有各种表名非正式引用。 系统无法强制重命名可以被命名为任何你喜欢的对象。 而且它并不关心。

当然,你不想无效引用这些名称的SQL代码。 显然,你不希望在应用程序逻辑引用他们改变名称。 通常这会不会是索引,序列或约束的名称的问题,因为这些通常不会用名字引用。

Postgres的重命名它们之前还收购对象上的锁。 所以,如果有对有关对象的任何类型的锁的并发事务开放,您RENAME操作停顿,直到这些事务提交或回滚。

系统目录和OID的

数据库模式被存储在系统模式系统目录的表pg_catalog 。 这里的说明书中的所有细节。 如果你不知道你在做什么, 你不应该用这些表都搞乱 。 棋错一,你可以把你的数据库。 使用DDL命令Postgres提供。

对于一些Postgres提供的最重要的表的对象标识符类型和类型转换为OID获取名称,反之亦然迅速。 喜欢:

SELECT 'foo_pkey_seq'::regclass

如果架构名称是search_path和表名是唯一的,是给你的一样:

SELECT oid FROM pg_class WHERE relname = 'foo_pkey_seq';

大多数目录表的主键是oid和内部,最引用使用的OID。



文章来源: Safely rename tables using serial primary key columns