Tengo una tabla que se crea de esta manera:
--
-- 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")
);
Más tarde se insertan algunas filas especificando la identificación:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
En un momento posterior se insertan algunos registros sin identificación y con el error:
Error: duplicate key value violates unique constraint
.
Aparentemente, la identificación se definió como una secuencia:
Cada inserción fallida aumenta el puntero en la secuencia hasta que se incrementa a un valor que ya no existe y las consultas tienen éxito.
SELECT nextval('jos_content_id_seq'::regclass)
¿Qué hay de malo con la definición de la tabla? ¿Cuál es la forma inteligente de solucionar esto?
postgresql
database-design
insert
auto-increment
sequence
Valentin Despa
fuente
fuente
Respuestas:
No hay nada malo con la definición de su tabla.
(Excepto el sombrero que usaría
jos_content_id
o algo así en lugar del nombre de columna no descriptivoid
.Y probablemente usaría en
text
lugar devarchar(50)
.Tu
INSERT
declaración es el problema.Con su
id
columna definida comoserial
, no debe insertar valores manuales paraid
. Esos pueden colisionar con el siguiente valor de la secuencia asociada.Proporcione una lista explícita de columnas de destino (que casi siempre es una buena idea para
INSERT
declaraciones persistentes ) y omita por completo las columnas en serie .Si necesita los valores de las columnas generadas automáticamente de inmediato, use la
RETURNING
cláusula :Más detalles en esta respuesta relacionada sobre SO:
Si tiene entradas manuales en
serial
columnas que pueden entrar en conflicto más adelante, configure su secuencia al máximo actualid
para solucionar esto una vez :¿Dónde
jos_content_id_seq
está el nombre predeterminado para una secuencia propiedad dejos_content.id
, que ya se encuentra en la columna predeterminada? Parece estarxhzt8_content_id_seq
en su caso;Actualización: surgió un problema similar en SO y se me ocurrió una nueva solución:
fuente