DDL: definir la estructura
Cómo se crean, se modifican y se destruyen los objetos de la base de datos, qué restricciones se les ponen a las columnas y en qué se diferencia vaciar una tabla con TRUNCATE de vaciarla con DELETE.
CREATE, ALTER y DROP
El lenguaje de definición de datos se resume en tres verbos que se combinan con cualquier objeto del esquema: CREATE lo crea, ALTER lo modifica y DROP lo elimina. No hace falta memorizar una lista de sentencias, sino entender que es una matriz de verbo por objeto.
- TABLE: la tabla, con sus columnas y sus restricciones.
- VIEW: la vista, una consulta guardada que se usa como si fuera una tabla.
- INDEX: el índice que acelera las búsquedas sobre una tabla.
- SEQUENCE: el generador de números correlativos, incorporado al estándar en 2003.
- PROCEDURE y FUNCTION: el código procedural guardado en el gestor.
- TRIGGER: el disparador asociado a una tabla.
- TYPE y DOMAIN: los tipos definidos por el usuario y los dominios de valores admitidos.
- SCHEMA: la agrupación de objetos que forma un espacio de nombres.
- ROLE: el conjunto de privilegios que se concede en bloque.
El DDL no manipula filas: manipula los objetos que las contienen. Si una sentencia toca datos y no estructura, ya no es DDL.
Para el examen
Los tres verbos: CREATE, ALTER y DROP
Sobre qué objetos: TABLE, VIEW, INDEX, SEQUENCE, PROCEDURE, TRIGGER, SCHEMA o ROLE
Lo que nunca hace: tocar filas
Crear una tabla
En un CREATE TABLE se declaran las columnas con su tipo y, a continuación, las restricciones que deben cumplirse. Poner nombre a cada restricción con la palabra CONSTRAINT no es obligatorio, pero es lo que permite después referirse a ella para quitarla o para entender un mensaje de error.
CREATE TABLE alumno (
id_alumno INTEGER NOT NULL,
correo VARCHAR(120) NOT NULL,
nombre VARCHAR(80) NOT NULL,
modalidad VARCHAR(10) NOT NULL,
fecha_alta DATE DEFAULT CURRENT_DATE,
CONSTRAINT pk_alumno PRIMARY KEY (id_alumno),
CONSTRAINT uq_alumno_correo UNIQUE (correo),
CONSTRAINT ck_alumno_modalidad
CHECK (modalidad IN ('largo', 'mediano', 'express'))
);
CREATE TABLE intento (
id_intento INTEGER NOT NULL,
id_alumno INTEGER NOT NULL,
id_tema INTEGER NOT NULL,
aciertos SMALLINT NOT NULL,
fallos SMALLINT NOT NULL,
realizado TIMESTAMP NOT NULL,
CONSTRAINT pk_intento PRIMARY KEY (id_intento),
CONSTRAINT fk_intento_alumno
FOREIGN KEY (id_alumno) REFERENCES alumno (id_alumno),
CONSTRAINT ck_intento_aciertos CHECK (aciertos >= 0)
);La clave ajena de la segunda tabla es la que sostiene la integridad referencial: se declara con FOREIGN KEY sobre la columna de la tabla hija y con REFERENCES apuntando a la tabla y a la columna de la tabla padre. A partir de ahí el gestor rechaza un intento cuyo alumno no exista, y rechaza también borrar un alumno que tenga intentos, salvo que se le haya dicho qué hacer en cascada.
Para el examen
FOREIGN KEY: nombra las columnas de la tabla hija
REFERENCES: apunta a la tabla padre
CONSTRAINT con nombre: opcional, pero permite retirar la restricción y leer los errores
Las restricciones de integridad
Una restricción es una regla que el gestor comprueba en cada inserción o modificación y que hace fracasar la sentencia si no se cumple. Puesta en la base de datos, la regla se cumple aunque los datos entren por otro programa distinto del previsto, que es justo lo que no se consigue validando solo en la aplicación.
| Restricción | Qué garantiza | Cuántas por tabla |
|---|---|---|
| PRIMARY KEY | Identifica cada fila de forma única y no admite nulos | Una sola |
| UNIQUE | No hay dos filas con el mismo valor; marca una clave candidata | Las que hagan falta |
| FOREIGN KEY | El valor existe en la tabla referenciada, o es nulo | Las que hagan falta |
| CHECK | El valor cumple una condición booleana sobre la propia fila | Las que hagan falta |
| NOT NULL | La columna siempre tiene valor | Una por columna |
El punto que más se falla es el de los nulos en UNIQUE. Como un nulo no es igual a otro nulo, el estándar admite varias filas con valor nulo en una columna UNIQUE, y así se comportan Oracle, PostgreSQL y MySQL. SQL Server es la excepción y solo tolera uno. La diferencia con PRIMARY KEY sí es firme en todos: una clave primaria no admite nulos en ninguna de sus columnas y solo puede haber una por tabla.
Para el examen
PRIMARY KEY: única por tabla y sin nulos
UNIQUE: tantas como hagan falta; admite varios nulos, salvo en SQL Server que solo uno
CHECK: valida la propia fila
NOT NULL: exige valor
Modificar y eliminar objetos
ALTER TABLE es la sentencia con la que evoluciona una base de datos ya en producción. Permite añadir y quitar columnas, cambiar el tipo o el valor por defecto de una columna existente, hacerla obligatoria y añadir o retirar restricciones.
ALTER TABLE alumno ADD COLUMN telefono VARCHAR(15);
ALTER TABLE alumno ALTER COLUMN modalidad SET DEFAULT 'largo';
ALTER TABLE alumno ALTER COLUMN nombre SET NOT NULL;
ALTER TABLE alumno ALTER COLUMN correo SET DATA TYPE VARCHAR(160);
ALTER TABLE alumno DROP COLUMN telefono;
ALTER TABLE intento
ADD CONSTRAINT ck_intento_fallos CHECK (fallos >= 0);
DROP TABLE intento;DROP es distinto de las demás: no vacía el objeto, lo hace desaparecer junto con todo lo que colgaba de él, índices y restricciones incluidos. Y como toda sentencia DDL, en la mayoría de gestores lleva un COMMIT implícito, de manera que no se deshace pidiendo un ROLLBACK.
Para el examen
Qué permite ALTER TABLE: añadir y quitar columnas y restricciones, y cambiar tipos
DROP: elimina el objeto entero con todo lo que cuelga
Efecto colateral del DDL: suele llevar COMMIT implícito
TRUNCATE: vaciar una tabla
TRUNCATE TABLE vacía la tabla entera de una sola vez. No admite condición WHERE: o se lleva todas las filas o no se usa. La estructura permanece, es decir, la tabla sigue existiendo con sus columnas, sus índices y sus restricciones, aunque algunos gestores la implementan por dentro destruyendo el objeto y volviéndolo a crear vacío.
La regla que hay que llevar al examen es que TRUNCATE no se puede deshacer, porque en Oracle y en MySQL el gestor confirma la operación automáticamente al tratarla como DDL. Conviene saber, eso sí, que no es una propiedad del lenguaje sino del producto: en PostgreSQL y en SQL Server TRUNCATE va dentro de la transacción y un ROLLBACK lo revierte.
TRUNCATE TABLE intento;
-- No es lo mismo que esto, aunque el resultado visible se parezca:
DELETE FROM intento;Para el examen
Qué hace: vacía la tabla entera de golpe, conservando la estructura
Lo que no admite: cláusula WHERE
Regla de examen: no se deshace en Oracle ni MySQL; PostgreSQL y SQL Server sí lo permiten dentro de la transacción
TRUNCATE frente a DELETE
Las dos dejan la tabla vacía, pero trabajan de forma completamente distinta y esa diferencia es material clásico de examen. DELETE recorre las filas y borra una a una, dejando constancia de cada borrado; TRUNCATE no mira las filas: libera de golpe el espacio que ocupaban.
| Aspecto | DELETE | TRUNCATE |
|---|---|---|
| Sublenguaje | DML | DDL en la mayoría de gestores |
| Admite WHERE | Sí, borra solo lo que se le diga | No, se lleva la tabla entera |
| Registro de la operación | Anota cada fila borrada | Libera el espacio reservado sin anotar fila por fila |
| Velocidad en tablas grandes | Lenta | Muy rápida |
| Disparadores de fila | Los ejecuta | No los ejecuta, porque no procesa filas |
| Vuelta atrás | Se deshace con ROLLBACK | En Oracle y MySQL no; en PostgreSQL y SQL Server sí |
Hay una consecuencia práctica que suele preguntarse en forma de trampa: como TRUNCATE no procesa filas, tampoco dispara los triggers de fila ni deja rastro fila a fila en el registro de transacciones. Si un sistema audita los borrados con un disparador, vaciar la tabla con TRUNCATE deja la auditoría en blanco.
Para el examen
DELETE: es DML, admite WHERE, dispara triggers y se deshace con ROLLBACK
TRUNCATE: es DDL, se lleva todo, es mucho más rápido y NO ejecuta los disparadores de fila