ams*_*ams 19 sql postgresql ddl database-design
我知道使用SERIAL主键的PostgreSQL表最终会有一个由PostgreSQL创建的隐式索引,序列和约束.问题是在重命名表时如何重命名这些隐式对象.下面是我尝试在最后通过具体问题解决这个问题.
给出一个像这样的表
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
value INTEGER
);
Run Code Online (Sandbox Code Playgroud)
Postgres输出
CREATE TABLE foo (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE foo OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
PgAdmin III显示以下作为表的DDL
ALTER table foo RENAME TO bar;
Run Code Online (Sandbox Code Playgroud)
现在重命名表
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;
Run Code Online (Sandbox Code Playgroud)
Postgres输出
ALTER SEQUENCE foo_pkey_seq RENAME TO bar_pkey_seq;
Run Code Online (Sandbox Code Playgroud)
表格的PgAdmin III SQL窗格
CREATE TABLE bar (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
注意额外的 SERIAL这意味着重命名表不会重命名主键的序列,但现在我们明确了这一点DEFAULT nextval('foo_pkey_seq'::regclass),.
现在重命名序列
我想保持数据库命名一致,所以我尝试了
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
value INTEGER
);
Run Code Online (Sandbox Code Playgroud)
在pgAdmin III中查看SQL窗格我看到了
CREATE TABLE foo (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE foo OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
该nextval()走了.
质询
DEFAULT nextval('foo_pkey_seq'::regclass),声明出现并消失?DEFAULT nextval('foo_pkey_seq'::regclass).如何重命名约束?Erw*_*ter 34
serial不是实际的数据类型.手册明确指出:
smallserial,serial和bigserial数据类型不是真正的类型,而仅仅是创建唯一标识符列的标记方便
执行以下所有操作后,解析伪数据类型:
创建一个名为的序列 smallserial
创建具有类型的列serial(或bigserial/ tablename_colname_seq分别为integer/ int2)
制作专栏 int8
使列拥有序列,以便自动删除它.
该系统不会不知道你是否做了这一切通过手工或伪数据类型的方式smallserial.pgAdmin检查列出的功能,如果满足所有功能,则使用匹配的串行类型简化反向工程DDL脚本.如果不满足其中一个功能,则不会进行此简化.这是pgAdmin所做的事情.对于底层目录表,它们都是一样的.没有这样的bigserial类型.
我很肯定没有办法自动重命名所拥有的序列.你可以跑
ALTER SEQUENCE ... RENAME TO ...
Run Code Online (Sandbox Code Playgroud)
像你一样.系统本身并不关心名称.该列NOT NULL DEFAULT nextval('tablename_colname_seq')存储一个serial(serial),您可以更改序列的名称而不会破坏它 - OID保持不变.数据库中的外键和类似引用也是如此.
主键的隐式索引绑定到PK约束的名称,如果更改表的名称,则不会更改PK约束的名称.在Postgres 9.2或更高版本中,您可以使用
ALTER TABLE ... RENAME CONSTRAINT ..
Run Code Online (Sandbox Code Playgroud)
也要纠正这一点.
还可以有参考表名称命名的索引.类似程序:
ALTER INDEX .. RENAME TO ..
Run Code Online (Sandbox Code Playgroud)
您可以对表名进行各种非正式引用.系统无法强制重命名可以命名的对象.它并不关心.
当然,您不希望使引用这些名称的SQL代码无效.显然,您不希望在应用程序逻辑引用它们时更改名称.通常,这对于索引,序列或约束的名称来说不是问题,因为这些通常不是由名称引用的.
在重命名对象之前,Postgres还会获取对象的锁定.因此,如果有并发事务打开,对相关对象有任何类型的锁定,则serial操作将停止,直到这些事务提交或回滚.
数据库模式存储在系统模式中的系统目录的表中DEFAULT.手册中的所有细节都在这里.如果你不确切地知道自己在做什么,那么你根本不应该弄乱这些表格.一个错误的举动,你可以打破你的数据库.使用Postgres提供的DDL命令.
对于一些最重要的表,Postgres提供对象标识符类型和类型转换以获取OID的名称,反之亦然.喜欢:
SELECT 'foo_pkey_seq'::regclass
Run Code Online (Sandbox Code Playgroud)
如果模式名称在,OID并且表名称是唯一的,则表示与以下内容相同:
SELECT oid FROM pg_class WHERE relname = 'foo_pkey_seq';
Run Code Online (Sandbox Code Playgroud)
大多数目录表的主键在'foo_pkey_seq'::regclass内部,大多数引用都使用OID.