我已经获得了我的 PostgreSQL 数据库的转储:
pg_dump -U user-name -d db-name -f dumpfile
Run Code Online (Sandbox Code Playgroud)
然后我继续在另一个数据库中恢复:
psql X -U postgres -d db-name-b -f dumpfile
Run Code Online (Sandbox Code Playgroud)
我的问题是数据库包含引用约束、检查和触发器,其中一些(特别是检查)在恢复过程中失败,因为信息没有按照会导致这些检查得到遵守的顺序加载。例如,在表中插入一行可能与CHECK调用一个plpgsql函数相关联,该函数检查某个条件是否在某个其他不相关的表中成立。如果后者没有psql在前者之前加载,则会发生错误。
下面是一个 SSCCE,它产生了这样一个一旦转储pg_dump就无法恢复的数据库:
CREATE OR REPLACE FUNCTION fail_if_b_empty () RETURNS BOOLEAN AS $$
SELECT EXISTS (SELECT 1 FROM b)
$$ LANGUAGE SQL;
CREATE TABLE IF NOT EXISTS a (
i INTEGER NOT NULL
);
INSERT INTO a(i) VALUES (0),(1);
CREATE TABLE IF NOT EXISTS b (
i INTEGER NOT NULL
);
INSERT INTO …Run Code Online (Sandbox Code Playgroud) postgresql database-design postgresql-9.1 pg-dump check-constraints
在PostgreSQL docs for Constraints 中,它说
非空约束在功能上等同于创建检查约束
CHECK (column_name IS NOT NULL),但在 PostgreSQL 中创建显式非空约束更有效。
我很好奇
CHECK (column_name IS NOT NULL)而不是有SET NOT NULL什么危害?我希望能够添加一个NOT VALID CHECK约束并单独验证它(因此AccessExclusiveLock仅在添加约束时保留一小段时间,然后ShareUpdateExclusiveLock为更长的验证步骤保留a ):
ALTER TABLE table_name
ADD CONSTRAINT column_constraint
CHECK (column_name IS NOT NULL)
NOT VALID;
ALTER TABLE table_name
VALIDATE CONSTRAINT column_constraint;
Run Code Online (Sandbox Code Playgroud)
代替:
ALTER TABLE table_name
ALTER COLUMN column_name
SET NOT NULL;
Run Code Online (Sandbox Code Playgroud) 添加NOT NULL带有DEFAULT值的列时- PostgreSQL 是否优化此操作?
如果表有 n 行,未优化的 alter-table-add-column 将产生 n 次写入默认值 - 显然,这可能非常痛苦。通过优化,数据库将立即创建新列,仅存储默认值的一个副本,当在合适的索引数据结构中找不到该列的非默认值时,该副本将返回。
例如Oracle 11g 就有这样的优化。
(前一个问题是:将多个列设置为非空时,Postgres 会使用多列索引吗?)
通常,当我将列设置为非空时,如果它没有索引,那么我首先添加它,以便 postgres 可以(希望)在锁定表的同时进行表扫描时使用索引,以便表被锁定在较短的时间内。
我想设置几列不为空,如下所示:
alter table foos
alter column bar1 set not null
alter column bar2 set not null
alter column bar3 set not null
alter column bar4 set not null;
Run Code Online (Sandbox Code Playgroud)
如果我为这些列创建了多列索引,那么在进行此更改之前,postgres 会在扫描锁定表时使用它吗?
CREATE INDEX CONCURRENTLY my_index on foos (bar1, bar2, bar3, bar4);
Run Code Online (Sandbox Code Playgroud)
如果我在 IS NULL(或 IS NOT NULL)上建立了部分索引怎么办
CREATE INDEX CONCURRENTLY my_index on foos (bar1, bar2, bar3, bar4) where bar1 is null and bar2 is null and bar3 is null and bar4 is null;
Run Code Online (Sandbox Code Playgroud) 该关系是在 Postgres 9.6 中使用以下命令创建的:
CREATE TABLE import_event (
import_event_id BIGINT NOT NULL,
filename VARCHAR (200) CONSTRAINT NN_import_event__filename NOT NULL
);
ALTER TABLE ONLY import_event ADD CONSTRAINT PK_import_cak_key PRIMARY KEY (import_event_id);
Run Code Online (Sandbox Code Playgroud)
请注意,not null 约束已命名。
然后执行了下面的命令
insert into import_event (import_event_id) values (1);
Run Code Online (Sandbox Code Playgroud)
当然,约束违反错误被提出。消息内容如下
ERROR: null value in column "filename" violates not-null constraint
DETAIL: Failing row contains (1, null).**strong text**
Run Code Online (Sandbox Code Playgroud)
问题是该消息中缺少非空约束的名称。但是,正确的错误消息:
ERROR: new row for relation "import_event" violates check constraint "nn_import_event__filename"
Run Code Online (Sandbox Code Playgroud)
当非空约束声明如下时产生
ALTER TABLE ONLY import_event ADD CONSTRAINT NN_import_event__filename CHECK(filename IS NOT NULL); …Run Code Online (Sandbox Code Playgroud) postgresql ×5
alter-table ×2
constraint ×1
ddl ×1
index ×1
locking ×1
null ×1
optimization ×1
pg-dump ×1