Lo más importante que hay que entender es que las tablas SQL no tienen un orden . El orden de las filas que ves cuando SELECT
sin ORDER BY
solo permanece igual porque es más rápido para la base de datos obtenerlos en ese orden que en otro orden. PostgreSQL solo devolverá filas en este orden cuando realice un escaneo secuencial en la tabla; si puede usar un índice para la consulta, generalmente obtendrá las filas en algún otro orden.
Puede encontrar esta respuesta que escribí anteriormente informativa.
En PostgreSQL, UPDATE
s a filas puede moverlos a una ubicación diferente dentro de la tabla, cambiando el orden en que se devuelven. También puede hacerlo el proceso de vacío automático en segundo plano y varias otras operaciones como VACUUM
y CLUSTER
.
Por lo tanto, debe nunca confíe en el orden "predeterminado" para cualquier cosa. Si desea dar algún tipo de orden a las filas, deben tiene una clave en la que puede ordenarlos.
Si ha creado una tabla sin una clave y ahora se da cuenta de que debería tener una, es posible que pueda recuperarse de la situación utilizando el ctid
columna del sistema. no confíe en esto para uso de producción, es una columna interna del sistema que es visible para los usuarios solo con fines de diagnóstico y recuperación de emergencia. Primero, vea si el orden físico en el disco es realmente el orden que desea:
SELECT row_number() OVER () AS mytable_id, *
FROM mytable
ORDER BY ctid;
Si es así, puede agregar una nueva columna de clave que esté preestablecida en una clave de incremento automático aplicada en el orden de las filas en el disco. Hay dos maneras de hacer esto. Lo más seguro es:
BEGIN;
LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE;
ALTER TABLE mytable RENAME TO mytable_old;
CREATE TABLE mytable (id SERIAL PRIMARY KEY, LIKE mytable_old INCLUDING ALL);
INSERT INTO mytable
SELECT row_number() OVER () AS id, *
FROM mytable_old
ORDER BY ctid;
SELECT setval('mytable_id_seq', (SELECT max(id)+1 FROM mytable));
COMMIT;
luego, una vez que esté seguro de que está satisfecho con los resultados, DROP TABLE mytable_old;
. Vea esta demostración:http://sqlfiddle.com/#!12/2cb99/2
Una forma rápida y fácil, pero menos segura, es simplemente crear la columna y confiar en que PostgreSQL reescriba la tabla de principio a fin:
ALTER TABLE mytable ADD COLUMN mytable_id SERIAL PRIMARY KEY;
No hay absolutamente ninguna garantía que PostgreSQL asignará los ID en orden, aunque en la práctica lo hará. Vea esta demostración de SQLFiddle.
Tenga en cuenta que cuando usa una SEQUENCE
(que es lo que un SERIAL
la columna crea) hay algunos comportamientos que quizás no espere. Cuando inserta varias filas a la vez, es posible que las filas no obtengan ID asignados necesariamente en el orden exacto que espera, y pueden "aparecer" (volverse visibles) en un orden diferente al orden en que se les asignaron ID e insertaron in. Además, si las transacciones retroceden, la ID generada se descarta para siempre, por lo que se producen lagunas en la numeración. Esto es muy bueno si desea que su base de datos sea rápida, pero no es ideal si desea una numeración sin espacios. Si eso es lo que necesita, busque "secuencia sin espacios postgresql".