У меня есть таблица, которая создана таким образом:
--
-- Table: #__content
--
CREATE TABLE "jos_content" (
"id" serial NOT NULL,
"asset_id" bigint DEFAULT 0 NOT NULL,
...
"xreference" varchar(50) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
Позже некоторые строки вставляются с указанием идентификатора:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
На более позднем этапе некоторые записи вставляются без идентификатора , и они завершаться с ошибкой:
Error: duplicate key value violates unique constraint
.
Видимо, идентификатор был определен как последовательность:
Каждая неудачная вставка увеличивает указатель в последовательности до тех пор, пока он не увеличится до значения, которого больше не существует, и запросы будут выполнены успешно.
SELECT nextval('jos_content_id_seq'::regclass)
Что не так с определением таблицы? Какой умный способ исправить это?
postgresql
database-design
insert
auto-increment
sequence
Валентин Деспа
источник
источник
Ответы:
Нет ничего плохого в вашем определении таблицы.
(За исключением того, что я бы использовал
jos_content_id
или что-то вместо неописательного имени столбцаid
.И я бы, вероятно, использовал
text
вместоvarchar(50)
.Ваше
INSERT
утверждение является проблемой.Когда ваш
id
столбец определен какserial
, вы не должны вставлять ручные значения дляid
. Они могут сталкиваться со следующим значением из связанной последовательности.Предоставьте явный список целевых столбцов (что почти всегда является хорошей идеей для постоянных
INSERT
операторов) и полностью опустите последовательные столбцы .Если вам нужно значение (я) автоматически сгенерированных столбцов сразу, используйте
RETURNING
предложение :Больше деталей в этом связанном ответе на SO:
Если у вас есть ручные записи в
serial
столбцах, которые могут конфликтовать позже, установите вашу последовательность на текущий максимум,id
чтобы исправить это один раз :Где
jos_content_id_seq
имя по умолчанию для последовательностиjos_content.id
, которой вы владеете, которую вы уже нашли в столбце default. Кажется,xhzt8_content_id_seq
в вашем случае;Обновление: аналогичная проблема возникла в SO, и я нашел новое решение:
источник