Necesito hacer cumplir una restricción única en la tabla en un campo de texto para asegurarme de que los usuarios no ingresen filas que contengan la misma dirección. Sin embargo, no quiero validarlo, los registros antiguos deben conservarse
He realizado algunas restricciones de verificación con una cláusula no válida, pero no estoy seguro de cómo hacerla única.
Cómo hacer que una restricción de verificación única no sea válida
Agregaría una nueva columna a la tabla:
ALTER TABLE atable ADD is_new boolean DEFAULT FALSE NOT NULL; ALTER TABLE atable ALTER is_new SET DEFAULT TRUE;Luego se marcarán las filas antiguas y podrá
CREATE UNIQUE ON atable (col1) WHERE is_new;que actuará como una "restricción única condicional".
Tenga en cuenta que agregar una columna con un valor predeterminado provocará una reescritura de la tabla (potencialmente lenta) antes de la versión 11.
no puedes:
https://www.postgresql.org/docs/current/sql-altertable.html
"AGREGAR table_constraint [NO VÁLIDO]
Este formulario agrega una nueva restricción a una tabla utilizando la misma sintaxis de restricción que CREAR TABLA, más la opción NO VÁLIDA, que actualmente solo está permitida para las restricciones de clave externa y COMPROBAR".
Además, las restricciones CHECK solo pueden funcionar en la fila actual, por lo que no pueden imponer la unicidad en todas las filas. Para hacer lo que quiere, está mirando un disparador ON INSERT.
Si entiendo correctamente, puede hacer esto usando una bandera. Pero desea configurar la bandera para que exactamente una fila para cada dirección existente tenga la bandera configurada.
ALTER TABLE t ADD address_for_duplicates boolean DEFAULT true NOT NULL; Luego, para las filas existentes, asumiré que tiene una clave principal, pk :
update t set address_for_duplicates = (seqnum = 1) from (select t.*, row_number() over (partition by address order by pk) as seqnum from t ) tt where tt.pk = t.pk;Ahora agregue un índice único filtrado:
create unique index unq_t_address_some_duplicates on t(address) where address_for_duplicates;Esto evitará que las direcciones existentes se dupliquen (nuevamente), así como las nuevas direcciones.