8

我想要一个仅在列不为空时强制执行约束的解决方案。我似乎无法在文档中找到执行此操作的方法。

create table mytable(
  table_identifier_a INTEGER,
  table_identifier_b INTEGER,
  table_value1,...)

根据数据的性质,我将在创建表时拥有标识符 b 和一个值。在我们收到额外的数据后,我将能够填充标识符 a。在这一点上,我想确保 aunique key of (identifier_a, value1)但仅当 identifier_a 存在时。

希望这是有道理的,有人有任何想法吗?

4

5 回答 5

8

嗯。唯一约束不会阻止多个 NULL 值。

CREATE TABLE mytable (
    table_identifier_a   INTEGER    NULL,
    table_identifier_b   INTEGER    NOT NULL,
    table_value1         INTEGER    NOT NULL,

    UNIQUE(table_identifier_a, table_identifier_b)
);

请注意,我们可以在其中插入多个 NULL,即使 identifier_b 匹配:

test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# select * from mytable;
 table_identifier_a | table_identifier_b | table_value1 
--------------------+--------------------+--------------
                    |                  1 |            2
                    |                  1 |            2
(2 rows)

但是我们不能创建重复的 (a,b) 对:

test=# update mytable set table_identifier_a = 3;
ERROR:  duplicate key value violates unique constraint "mytable_table_identifier_a_key"

当然,您确实有一个问题:您的表没有主键。您可能有数据模型问题。但是你没有提供足够的细节来解决这个问题。

于 2009-02-24T02:06:42.853 回答
1

如果在一个事务中完成整个操作是可行的,则可以更改 postgres 评估约束的时间,即:

START;
SET CONSTRAINTS <...> DEFERRED;
<SOME INSERT/UPDATE/DELETE>
COMMIT;

在这种情况下,约束在提交时进行评估。请参阅: Postgres 7.4 Doc - 设置约束Postgres 8.3 Doc

于 2009-02-23T22:54:58.977 回答
1

实际上,我可能会将其分解为两张表。您正在对两种不同的事物进行建模。第一个是初始版本,只是部分的,第二个是完整的。一旦需要将第一种事物带到第二种事物所需的信息,将行从一个表移动到另一个表。

于 2009-02-24T02:41:23.880 回答
0

您可以使用触发器而不是约束来处理此问题。

于 2009-02-23T22:44:04.213 回答
0

如果我是你,我会将表拆分为两个表,并可能创建根据需要组合它们的视图。

于 2009-02-23T22:48:16.233 回答