Skip to content

¿Qué es un índice único parcial en PostgreSQL? ​

Un índice único parcial (Partial Unique Index) es un índice que impone una regla de unicidad únicamente sobre las filas que cumplen una condición determinada.

A diferencia de una restricción UNIQUE convencional, que se aplica a todas las filas de las columnas indicadas, un índice único parcial permite establecer reglas que afectan solamente a un subconjunto de los registros.

1. Sintaxis ​

sql
CREATE UNIQUE INDEX nombre_indice
ON nombre_tabla (columna1, columna2)
WHERE condicion;

Sus componentes son:

  • CREATE UNIQUE INDEX: crea un índice que impide duplicados entre las filas incluidas.
  • ON nombre_tabla (columna1, columna2): define las columnas cuya combinación debe ser única.
  • WHERE condicion: determina qué filas participan en el índice.

Las filas que no cumplen la condición quedan fuera del índice y no están sujetas a esa regla de unicidad.

2. Ejemplo práctico ​

En la tabla ATRIBUTO_CATEGORIA, cada categoría puede tener varios atributos, como Ancho, Perfil y Diámetro. Queremos que los atributos activos de una misma categoría tengan órdenes únicos, pero permitir que los atributos desactivados conserven sus posiciones históricas.

sql
CREATE UNIQUE INDEX uq_atributo_categoria_orden_activo
ON ATRIBUTO_CATEGORIA (id_categoria, orden)
WHERE activo = TRUE;

Esta definición significa que no pueden existir dos filas activas con la misma combinación de id_categoria y orden.

3. ¿Cómo funciona? ​

Supongamos que existen estos registros:

id_categorianombreordenactivo
1Ancho1TRUE
1Perfil2TRUE
1Ancho antiguo1FALSE
2Ancho1TRUE

Todos son válidos.

  • Ancho y Perfil tienen órdenes distintos dentro de la categoría 1.
  • Ancho antiguo está desactivado y no participa en el índice.
  • La categoría 2 puede tener su propio atributo en el orden 1 porque la combinación de categoría y orden es diferente.

En cambio, intentar insertar otro atributo activo con id_categoria = 1 y orden = 1 generaría un error por duplicación.

4. ¿Qué ocurre cuando se activa o desactiva un registro? ​

PostgreSQL mantiene el índice automáticamente.

  • Al desactivar un atributo: deja de participar en el índice y su posición puede reutilizarse.
  • Al activar un atributo: PostgreSQL comprueba que no exista otra fila activa con la misma combinación de categoría y orden.
  • Al cambiar el orden: la nueva combinación debe seguir siendo única entre las filas activas.

No es necesario actualizar el índice manualmente.

5. Diferencia entre UNIQUE e índice único parcial ​

CaracterísticaUNIQUE convencionalÍndice único parcial
Filas afectadasTodas las filasSolo las que cumplen el WHERE
Permite reutilizar valores de filas inactivasNo, si siguen duplicando la combinaciónSí, si quedan fuera del índice
EjemploUNIQUE (id_categoria, orden)UNIQUE INDEX ... WHERE activo = TRUE

Importante: si ya existe una restricción UNIQUE (id_categoria, orden), debes eliminarla para permitir la reutilización de órdenes entre registros activos e inactivos. La restricción anterior seguiría bloqueando esos duplicados aunque crees el índice parcial.

6. ¿El índice solo sirve para validar datos? ​

No. Un índice también puede mejorar el rendimiento de consultas que utilizan sus columnas y cuya condición permite aprovecharlo.

Por ejemplo:

sql
SELECT *
FROM ATRIBUTO_CATEGORIA
WHERE id_categoria = 1
  AND activo = TRUE
ORDER BY orden;

PostgreSQL puede aprovechar el índice para esta consulta, aunque el beneficio real depende del volumen de datos y del plan de ejecución.

7. ¿Cuándo conviene utilizarlo? ​

Los índices únicos parciales son especialmente útiles cuando necesitas:

  • Permitir un único registro activo por combinación de valores.
  • Evitar duplicados solo entre registros vigentes.
  • Conservar registros históricos sin que interfieran con los actuales.
  • Aplicar reglas de unicidad condicionales sin duplicar datos ni eliminar registros antiguos.

En resumen: un índice único parcial permite exigir unicidad únicamente sobre las filas que cumplen una condición. En nuestro caso, garantiza que los atributos activos de una categoría tengan posiciones únicas, sin impedir que los atributos desactivados conserven sus posiciones históricas.