Restricciones: reglas para los datos
En resumen: Las restricciones (NOT NULL, DEFAULT, UNIQUE, CHECK, PRIMARY KEY) son reglas escritas en CREATE TABLE con las que la propia base de datos rechaza las filas incorrectas.
Problema
Una tabla que acepta cualquier cosa
Aquí tienes una tabla para los proveedores sin ninguna regla. Ejecuta la consulta:
Entró un proveedor sin nombre. El mismo número de IVA entró dos veces. Entró una valoración de 7 en una escala del 1 al 5. Nadie comprobó nada.
En el módulo sobre cambiar los datos, la tienda rechazaba filas así con errores. Esos errores vienen de reglas escritas en CREATE TABLE. Ahora las escribirás tú.
La idea
NOT NULL y DEFAULT
Las reglas se escriben después del tipo de la columna. Se llaman restricciones (constraints).
NOT NULL: la columna no puede estar vacía.DEFAULT valor: lo que se guarda si elINSERTno da ningún valor.
La lechería recibió «Sofía», porque no se dio su ciudad. Un proveedor sin nombre no entra:
DEFAULT CURRENT_DATE guarda la fecha de hoy. Es útil para «cuándo se añadió»:
1 significa «sí, es la fecha de hoy». Cambia added_at = CURRENT_DATE por added_at solo y verás la fecha misma.
Más precisamente, para curiosos
CURRENT_DATE en SQLite es la fecha en UTC, no en hora local. En Bulgaria, entre la medianoche y las 2 o 3 de la madrugada, la fecha local ya es la nueva mientras que UTC todavía tiene la anterior. CURRENT_TIMESTAMP da la fecha y la hora, también en UTC.
Pruébalo
Los campos obligatorios
La tabla deliveries tiene id, supplier_id, amount y status. Haz obligatorios el proveedor y el importe, y el estado obligatorio con el valor por defecto 'expected'.
Solución
CREATE TABLE deliveries (
id INTEGER PRIMARY KEY,
supplier_id INTEGER NOT NULL,
amount REAL NOT NULL,
status TEXT NOT NULL DEFAULT 'expected'
);supplier_id INTEGER NOT NULL, amount REAL NOT NULL, status TEXT NOT NULL DEFAULT 'expected'. Una entrega nueva se puede guardar sin estado: es «expected» hasta que llega.
La idea
UNIQUE
UNIQUE prohíbe dos valores iguales en la columna. Una empresa tiene un número de IVA:
A veces lo único es el par. Cada proveedor da un precio por producto. Dos proveedores pueden ofrecer el mismo producto, y un proveedor ofrece muchos productos. La regla se escribe aparte, después de las columnas, con las dos columnas entre paréntesis:
Las tres primeras filas entran. La cuarta es un segundo precio del proveedor 1 para el producto 1.
Más precisamente, para curiosos
UNIQUE permite muchos NULL: dos proveedores sin número de IVA no cuentan como iguales, porque NULL no es igual a NULL. Si el número de IVA es obligatorio, escribe vat TEXT NOT NULL UNIQUE. PostgreSQL funciona igual. SQL Server por defecto deja entrar un solo NULL en una columna UNIQUE.
La idea
CHECK
CHECK (condición) deja entrar la fila solo si la condición es verdadera. La condición es como la de WHERE:
Cuando la condición es sobre varias columnas, CHECK va después de las columnas. Una promoción no puede terminar antes de empezar:
El mensaje de SQLite dice qué condición falló. Por eso conviene que las condiciones sean cortas y claras.
Míralo
CHECK deja pasar NULL
La valoración va de 1 a 5. ¿Y si no se da?
Entró. CHECK rechaza la fila solo cuando la condición es falsa. NULL BETWEEN 1 AND 5 es «desconocido», como toda comparación con NULL. Es lo contrario de WHERE, que se queda solo con lo verdadero.
Aquí es lo correcto: un proveedor nuevo todavía no tiene valoración. Pero si el valor es obligatorio, CHECK no basta. Necesitas además NOT NULL.
Pruébalo
Los precios de los proveedores
La tabla supplier_prices tiene supplier_id, product_id y price. El precio es obligatorio y mayor que 0, y cada proveedor tiene un solo precio para un producto dado. Añade las reglas.
Solución
CREATE TABLE supplier_prices (
supplier_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
price REAL NOT NULL CHECK (price > 0),
UNIQUE (supplier_id, product_id)
);price REAL NOT NULL CHECK (price > 0) y en una línea aparte UNIQUE (supplier_id, product_id). Sin NOT NULL, un precio NULL pasaría por CHECK.
La idea
PRIMARY KEY
Ya conoces la clave primaria: la columna por la que se reconoce una fila. En CREATE TABLE es una restricción como las demás. No deja entrar dos filas con la misma clave:
Cuando la clave tiene dos columnas, se escribe aparte, como UNIQUE. Así es en order_items: un producto está una vez en un pedido, y la cantidad está en quantity.
order_items
- PK
order_idinteger→ orders - PK
product_idinteger→ products quantityinteger *unit_pricereal *
Más precisamente, para curiosos
SQLite tiene una rareza antigua: una clave primaria que no es INTEGER PRIMARY KEY acepta NULL. Ejecútalo:
Dos cupones sin código. Es un error de las primeras versiones que se conservó para que los programas antiguos no se rompan. En una tabla STRICT la clave primaria no acepta NULL. En todos los demás casos, escribe code TEXT NOT NULL PRIMARY KEY. En PostgreSQL y MySQL la clave primaria siempre es NOT NULL.
Ejercicio
Los proveedores, bien hechos
Crea la tabla suppliers definitiva: id (clave primaria), name (obligatorio), vat (número de IVA, obligatorio y sin repeticiones), city (obligatoria, con el valor por defecto 'Sofía') y rating (un número entero de 1 a 5, puede faltar). La comprobación también intentará añadir proveedores malos.
Solución
CREATE TABLE suppliers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
vat TEXT NOT NULL UNIQUE,
city TEXT NOT NULL DEFAULT 'Sofía',
rating INTEGER CHECK (rating BETWEEN 1 AND 5)
);name TEXT NOT NULL, vat TEXT NOT NULL UNIQUE, city TEXT NOT NULL DEFAULT 'Sofía' y rating INTEGER CHECK (rating BETWEEN 1 AND 5).
La comprobación intenta añadir siete proveedores. Solo los dos correctos deben entrar. El número de IVA repetido, el proveedor sin nombre, el que no tiene número de IVA, el que no tiene ciudad y la valoración de 7 se quedan fuera.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Funciones de fecha · Clave primaria y clave foránea · INSERT: insertar filas · CREATE TABLE: crear una tabla
- Continúa en: Claves foráneas: vínculos entre tablas · ALTER TABLE: cambiar una tabla · Tipos de relación: 1:1, 1:N, M:N · Diagrama ER: de la descripción al esquema
- Ejercicios sobre el tema: Tablas y reglas