Я посмотрел на INSERT INTO .. ON CONFLICT (..) DO UPDATE ..
синтаксис PostgreSQL и понял, что вы не можете сделать несколько уникальных проверок ограничений с ним. Я имею в виду, что вы либо ссылаетесь на составной уникальный индекс по именам столбцов ON CONFLICT (Name, Symbol)
(если уникальный индекс определен для этих двух столбцов), либо используете первичный ключ. Если вы определяете два отдельных уникальных индекса для столбцов, вы можете проверить только один.
CREATE TABLE student
(Id int primary key, Name varchar(50), Symbol varchar(50),
CONSTRAINT col1_unique UNIQUE (Name),
CONSTRAINT col2_unique UNIQUE (Symbol)
);
INSERT INTO student
(Id, Name, Symbol)
VALUES
(1, 'John', 'J'),
(2, 'David', 'D'),
(3, 'Will', 'W');
INSERT INTO student
(Id, Name, Symbol)
VALUES
(4, 'Jeremy', 'J')
on conflict(Name) DO UPDATE
set Name = 'Jeremy';
Может выдать ошибку, говоря, J
является дубликатом. Однако этот пример просто плохой дизайн, потому что Символ должен быть в другой таблице и быть связан с таблицей ученика через отношение один ко многим. Вот почему мне интересно, может быть, PostgreSQL on conflict
был спроектирован таким образом, потому что вы ВСЕГДА можете реструктурировать таблицы таким образом, чтобы в них был только один уникальный индекс. Это правда или есть другая причина?
Пример скрипки: http://www.sqlfiddle.com/#!17/9c0ce
источник
Ответы:
Всегда есть Шестой, или Ключ Домена, Нормальная Форма. Здесь каждый неключевой столбец становится собственной таблицей. Таким образом, таблица 3NF T (Key, Col1, Col2, ..) становится T1 (Key, Col1), T2 (Key, Col2) и т. Д. Те новые таблицы, которым требуется уникальность, могут быть объявлены.
Однако я думаю, что иметь несколько уникальных ограничений на таблицу - это нормально. Взять хотя бы таблицу стран. Это будет, скажем, ID, название, код ISO, столица и некоторые другие. Каждый из этих первых четырех будет уникальным. Более того, если мы хотим, чтобы наша система опиралась на уникальность каждого, я считаю, что мы должны определить уникальные ограничения для каждого из них. Это обеспечивает правду о данных, на которые могут положиться все потребители.
источник
MERGE
инструкцию). PgON CONFLICT DO UPDATE
был добавлен только в 9.5 и намного более ограничен.ON CONFLICT DO NOTHING
без упоминания уникальных ограничений, и он будет учитывать все из них (и ничего не делать). Когда вы хотите сделатьON CONFLICT DO UPDATE
, вы должны объявить столбец или ограничение и только один. Ограничение может быть снято в будущих версиях.ON CONFLICT ... DO UPDATE
и, к сожалению, этот ответ не решает эту проблему.