我知道使用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 ms没有结果。
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 ms没有结果。
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)
语句出现并消失? foo_pkey
。如何重命名约束?答案 0 :(得分:33)
serial
不是实际的数据类型。 The manual states:
数据类型
smallserial
,serial
和bigserial
不是真正的类型, 但仅仅是创建唯一标识符列的标记方便
解决伪数据类型的所有这些:
创建名为tablename_colname_seq
分别为integer
/ int2
创建int8
(或smallserial
/ bigserial
类型的列
制作专栏NOT NULL DEFAULT nextval('tablename_colname_seq')
使列拥有序列,以便自动将其删除
系统不知道您是手动还是通过伪数据类型serial
完成所有这些操作。 pgAdmin检查列出的功能,如果满足所有功能,则使用匹配的serial
类型简化反向工程DDL脚本。如果不满足其中一个功能,则不会进行此简化。这是pgAdmin所做的事情。对于底层目录表,它们都是一样的。这样没有serial
类型。
无法自动重命名已拥有的序列。你可以运行:
ALTER SEQUENCE ... RENAME TO ...
像你一样。系统本身并不关心名称。列DEFAULT
存储OID
('foo_pkey_seq'::regclass
),您可以更改序列的名称而不会破坏 - OID保持不变。对于数据库中的外键和类似引用也是如此。
主键的隐式索引绑定到PK约束的名称,如果更改表的名称,不将更改。 In Postgres 9.2 or later you can use
ALTER TABLE ... RENAME CONSTRAINT ..
也要纠正这一点。
也可以在引用表名时命名索引。 Similar procedure:
ALTER INDEX .. RENAME TO ..
您可以对表名进行各种非正式引用。系统无法强制重命名可以命名的对象。它并不关心。
当然,您不希望使引用这些名称的SQL代码无效。显然,您不希望在应用程序逻辑引用它们时更改名称。通常这对于索引,序列或约束的名称来说不是问题,因为这些名称通常不会被名称引用。
Postgres在重命名对象之前还获取对象的锁定。因此,如果有并发事务打开,对相关对象有任何锁定,则RENAME
操作将停止,直到这些事务提交或回滚为止。
数据库架构存储在系统架构pg_catalog
中的系统目录的表中。 All details in the manual here.如果您不确切知道自己在做什么,根本不应该弄乱这些表格。一个错误的举动,你可以打破你的数据库。 Use the DDL commands Postgres provides.
对于一些最重要的表格,Postgres提供object identifier types并输入类型转换来获取OID的名称,反之亦然。像:
SELECT 'foo_pkey_seq'::regclass
如果架构名称在search_path
中且表名是唯一的,则表示与以下内容相同:
SELECT oid FROM pg_class WHERE relname = 'foo_pkey_seq';
大多数目录表的主键是oid
,在内部,大多数引用都使用OID。