相关疑难解决方法(0)

恢复转储时禁用所有约束和表检查

我已经获得了我的 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

22
推荐指数
1
解决办法
4万
查看次数

Postgres:SET NOT NULL 如何比 CHECK 约束“更有效”

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)

postgresql check-constraints postgresql-9.5

22
推荐指数
1
解决办法
2315
查看次数

PostgreSQL 是否优化添加具有非 NULL DEFAULT 的列?

添加NOT NULL带有DEFAULT值的列时- PostgreSQL 是否优化此操作?

如果表有 n 行,未优化的 alter-table-add-column 将产生 n 次写入默认值 - 显然,这可能非常痛苦。通过优化,数据库将立即创建新列,仅存储默认值的一个副本,当在合适的索引数据结构中找不到该列的非默认值时,该副本将返回。

例如Oracle 11g 就有这样的优化

postgresql optimization alter-table ddl

12
推荐指数
2
解决办法
8490
查看次数

如何在表扫描期间不锁定表的情况下将列设置为 NOT NULL?

(前一个问题是:将多个列设置为非空时,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)

postgresql index null alter-table locking

5
推荐指数
1
解决办法
928
查看次数

错误消息中缺少非空约束的名称

该关系是在 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 constraint postgresql-9.6

4
推荐指数
1
解决办法
1076
查看次数