Bizonozubr
@Bizonozubr
IT специалист в не IT сфере

Откуда появляются отрицательные значения индекса первичного ключа PostgreSQL?

Появился следующий вопрос в плане работы с PostgreSQL через Entity Framework.

Имеется следующая таблица:
CREATE TABLE "TankContentStateHistory" (
"TankContentStateHistoryId" integer NOT NULL SET DEFAULT nextval('"TankContentStateHistory_TankContentStateHistoryId_seq"'::regclass),
"AverageTemperature" double precision NOT NULL,
...
"GTVolume" double precision DEFAULT 0.0 NOT NULL);


TankContentStateHistoryId берет свои значения из перечисления TankContentStateHistory_TankContentStateHistoryId_seq:
CREATE SEQUENCE "TankContentStateHistory_TankContentStateHistoryId_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


Значения должны быть все время положительными, но в последнее время стали появляться моменты, когда первичный ключ становится с отрицательным значением и откуда оно берется - не понятно. Логи PostgreSQL ясности не вносят:
2021-09-19 00:45:58 MSK ОШИБКА:  повторяющееся значение ключа нарушает ограничение уникальности "PK_TankContentStateHistory"
2021-09-19 00:45:58 MSK ПОДРОБНОСТИ:  Ключ "("TankContentStateHistoryId")=(-2147482602)" уже существует.
2021-09-19 00:45:58 MSK ОПЕРАТОР:  INSERT INTO "TankContentStateHistory" ("TankContentStateHistoryId", ... "GTVolume")
VALUES ($1, ..)


EntityFrameworkCore по сути дублирует тоже самое:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Npgsql.PostgresException: 23505: повторяющееся значение ключа нарушает ограничение уникальности "PK_TankContentStateHistory"
в Npgsql.NpgsqlConnector.<>c__DisplayClass161_0.<<ReadMessage>g__ReadMessageLong|0>d.MoveNext()


Вопрос в следующем - в каком месте может возникнуть проблема? Потому что после тщетных попыток уставить значение, все следующие значения ключа идет дальше по последовательности (например, id = 2044, потом отрицательное значение id=-454635, после id=2045).
  • Вопрос задан
  • 902 просмотра
Решения вопроса 1
Пригласить эксперта
Ответы на вопрос 2
rozhnev
@rozhnev
Fullstack programmer, DBA, медленно, дорого
А почему бы не использовать встроеный тип serial вместо TankContentStateHistory_TankContentStateHistoryId_seq
CREATE TABLE "TankContentStateHistory" (
  "TankContentStateHistoryId" serial NOT NULL,
  "AverageTemperature" double precision NOT NULL,
  "GTVolume" double precision DEFAULT 0.0 NOT NULL
);

INSERT INTO "TankContentStateHistory" ("AverageTemperature", "GTVolume") VALUES (10, 20);

SELECT * FROM "TankContentStateHistory";


PostgreSQL fiddle
Ответ написан
kingleonfromafrica
@kingleonfromafrica
from Africa
Отрицательные значения признак того, что у Вас счетчик "на второй круг пошел".
Поменяйте на BigInt.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы