Hasta ahora hemos visto las restricciones:
NULL
NOT NULL
DEFAULT
Estas nos permiten controlar si una columna puede estar vacía o si debe recibir un valor predeterminado.
Sin embargo, existe otro problema común:
¿Cómo evitar que un mismo valor se almacene varias veces?
Por ejemplo:
Dos usuarios con el mismo correo electrónico.
Dos empleados con el mismo número de empleado.
Dos productos con el mismo código.
Para resolver este problema PostgreSQL proporciona la restricción UNIQUE.
🧠 ¿Qué es UNIQUE?
La restricción UNIQUE garantiza que los valores almacenados en una columna no se repitan.
En otras palabras:
✅ Valores diferentes son permitidos.
❌ Valores duplicados generan error.
🏗️ Sintaxis Básica
La forma más simple de definirla es durante la creación de una tabla.
CREATE TABLE usuarios (
id INTEGER,
nombre VARCHAR(100),
email VARCHAR(200) UNIQUE
);
En este ejemplo:
Dos usuarios pueden tener distintos correos.
No pueden existir dos usuarios con el mismo correo.
✅ Insertar Valores Únicos
Creamos la tabla:
CREATE TABLE usuarios (
id INTEGER,
nombre VARCHAR(100),
email VARCHAR(200) UNIQUE
);
Insertamos el primer usuario:
INSERT INTO usuarios (
id,
nombre,
)
VALUES (
1,
'Juan Pérez',
'juan@email.com'
);
Insertamos un segundo usuario:
INSERT INTO usuarios (
id,
nombre,
)
VALUES (
2,
'Ana López',
'ana@email.com'
);
Ambos registros se insertan correctamente porque los correos son diferentes.
❌ Intentar Insertar un Duplicado
Ahora intentemos insertar un correo que ya existe.
INSERT INTO usuarios (
id,
nombre,
)
VALUES (
3,
'Carlos García',
'juan@email.com'
);
PostgreSQL devolverá un error similar a:
ERROR: duplicate key value violates unique constraint
La inserción falla porque el valor:
juan@email.com
ya se encuentra almacenado.
🔍 Verificando los Datos
Podemos consultar la tabla:
SELECT *
FROM usuarios;
Resultado:
id | nombre | email
----+-------------+----------------
1 | Juan Pérez | juan@email.com
2 | Ana López | ana@email.com
Observa que el tercer registro nunca fue insertado.
📝 UNIQUE en Otras Columnas
La restricción no está limitada a correos electrónicos.
También suele utilizarse en:
RFC
CURP
Número de empleado
Código de producto
Nombre de usuario
Número de serie
Ejemplo:
CREATE TABLE productos (
codigo VARCHAR(50) UNIQUE,
nombre VARCHAR(100),
precio NUMERIC(10,2)
);
🧪 Ejemplo Completo
Crear Tabla
CREATE TABLE empleados (
numero_empleado INTEGER UNIQUE,
nombre VARCHAR(100),
departamento VARCHAR(100)
);
Insertar Datos
INSERT INTO empleados (
numero_empleado,
nombre,
departamento
)
VALUES
(
1001,
'Juan Pérez',
'Tecnología'
),
(
1002,
'Ana López',
'Finanzas'
);
Consultar
SELECT *
FROM empleados;
Resultado:
numero_empleado | nombre | departamento
----------------+-------------+--------------
1001 | Juan Pérez | Tecnología
1002 | Ana López | Finanzas
Intentar duplicar el número de empleado
INSERT INTO empleados (
numero_empleado,
nombre,
departamento
)
VALUES (
1001,
'Carlos García',
'Ventas'
);
Resultado:
ERROR: duplicate key value violates unique constraint
⚠️ UNIQUE y Valores NULL
Este es uno de los comportamientos que más confunde a quienes comienzan con PostgreSQL.
Supongamos la siguiente tabla:
CREATE TABLE clientes (
id INTEGER,
email VARCHAR(200) UNIQUE
);
Ahora insertamos:
INSERT INTO clientes (id, email)
VALUES (1, NULL);
y posteriormente:
INSERT INTO clientes (id, email)
VALUES (2, NULL);
Ambas inserciones son válidas.
¿Por qué ocurre esto?
Porque PostgreSQL considera que:
NULL != NULL
Un valor nulo significa "valor desconocido", por lo que múltiples registros pueden contener NULL en una columna UNIQUE.
Por esta razón es común combinar:
UNIQUE
con
NOT NULL
🔒 UNIQUE + NOT NULL
Esta es probablemente la combinación más utilizada.
CREATE TABLE usuarios (
id INTEGER,
email VARCHAR(200) NOT NULL UNIQUE
);
Con esta definición:
✅ El correo es obligatorio.
✅ No puede repetirse.
❌ No puede ser NULL.
🏗️ UNIQUE a Nivel de Tabla
Hasta ahora hemos definido UNIQUE directamente sobre una columna.
También puede definirse al final de la tabla.
CREATE TABLE usuarios (
id INTEGER,
nombre VARCHAR(100),
email VARCHAR(200),
UNIQUE(email)
);
El comportamiento es exactamente el mismo.
🔧 Agregar UNIQUE a una Tabla Existente
Si la tabla ya existe:
ALTER TABLE usuarios
ADD CONSTRAINT uq_usuarios_email
UNIQUE(email);
A partir de ese momento PostgreSQL impedirá valores duplicados.
🔧 Eliminar una Restricción UNIQUE
Primero identificamos el nombre de la restricción.
Posteriormente:
ALTER TABLE usuarios
DROP CONSTRAINT uq_usuarios_email;
🎯 UNIQUE en Múltiples Columnas
También podemos exigir que una combinación de columnas sea única.
Supongamos una tabla de cursos.
CREATE TABLE inscripciones (
alumno VARCHAR(100),
curso VARCHAR(100),
CONSTRAINT uq_inscripciones_alumno_curso
UNIQUE(alumno, curso)
);
Esto significa:
✅ Juan puede inscribirse a SQL.
✅ Juan puede inscribirse a PostgreSQL.
✅ Ana puede inscribirse a SQL.
❌ Juan no puede inscribirse dos veces al mismo curso.
Ejemplo
INSERT INTO inscripciones
VALUES ('Juan', 'PostgreSQL');
Luego:
INSERT INTO inscripciones
VALUES ('Juan', 'PostgreSQL');
Resultado:
ERROR: duplicate key value violates unique constraint
💡 Buenas Prácticas
Utiliza UNIQUE en datos que realmente deban ser únicos
Ejemplos comunes:
usuario
rfc
curp
codigo_producto
numero_empleado
Combínalo con NOT NULL cuando corresponda
En muchos casos ambos requisitos son necesarios.
email VARCHAR(200) NOT NULL UNIQUE
Asigna nombres descriptivos a las restricciones
Por ejemplo:
ALTER TABLE usuarios
ADD CONSTRAINT uq_usuarios_email
UNIQUE(email);
Esto facilita la identificación de errores y el mantenimiento de la base de datos.
No agregues UNIQUE innecesariamente
Pregúntate siempre:
¿Este dato realmente debe ser único?
Por ejemplo, normalmente no tendría sentido que el nombre de una persona fuera único:
nombre VARCHAR(100) UNIQUE
Podrían existir múltiples personas llamadas "Juan Pérez".
✅ Conclusión
La restricción UNIQUE permite garantizar que ciertos valores no se repitan dentro de una tabla.
Los conceptos más importantes son:
UNIQUE evita valores duplicados.
Puede definirse sobre una o varias columnas.
Los intentos de insertar valores repetidos generan error.
Varias filas pueden contener NULL en una columna UNIQUE.
Es habitual combinar UNIQUE con NOT NULL.
Se utiliza frecuentemente para correos electrónicos, nombres de usuario, códigos de producto y números de empleado.