Как я могу применить ограничение, только если столбец не равен null в Postgresql?

Я хотел бы, чтобы решение применяло ограничение только в том случае, если столбец не равен null. Я не могу найти способ сделать это в документации.

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

Do к природе данных, у меня будет идентификатор b и значение при создании таблицы. После того, как мы получим дополнительные данные, я смогу заполнить идентификатор a. На данный момент я хотел бы обеспечить unique key of (identifier_a, value1) но только если identifier_a существует.

надеюсь, что это имеет смысл, у любого есть идеи?

5 ответов


Эммм. Уникальные ограничения не препятствуют нескольким нулевым значениям.

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)
);

обратите внимание, что мы можем вставить в него Muliple NULLs, даже когда 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"

конечно, у вас есть проблема: ваша таблица не имеет первичного ключа. Вы вероятно, есть проблема с моделью данных. Но вы не предоставили достаточно детали исправить.


Если возможно выполнить всю операцию в рамках одной транзакции, можно изменить время, в которое postgres оценивает ограничение, т. е.:

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

в этом случае ограничение производится при фиксации. Видеть: Postgres 7.4 Doc-установить ограничения или Postgres 8.3 Doc


на самом деле, я бы, вероятно, разбил это на две таблицы. Ты моделируешь два разных типа вещей. Первая-это начальная версия, которая является только частичной,а вторая-это все. Как только информация, необходимая для приведения первого вида вещей ко второму, переместите строку из одной таблицы в другую.


вы можете справиться с этим, используя триггер вместо ограничения.


на вашем месте я бы разделил таблицу на две таблицы и, возможно, создал представление, которое объединяет их по мере необходимости.