UD05 · Definición y control de datos (DDL y DCL)
Resumen del tema
Hasta ahora hemos diseñado. En esta unidad implementamos: convertimos el esquema relacional en tablas reales dentro de un SGBD. Para ello usamos dos sublenguajes de SQL:
- DDL (Data Definition Language): crea, modifica y elimina la estructura (tablas, restricciones, índices, vistas, secuencias).
- DCL (Data Control Language): controla quién puede hacer qué (usuarios, roles y privilegios).
Todos los ejemplos usan Oracle AI Database 26ai Free. Cuando una característica sea propia de Oracle o de una versión concreta, se indica.
RA2 Crea bases de datos definiendo su estructura y las características de sus elementos según el modelo relacional. 8 CE
- RA2.a Se ha analizado el formato de almacenamiento de la información.
- RA2.b Se han creado las tablas y las relaciones entre ellas.
- RA2.c Se han seleccionado los tipos de datos adecuados.
- RA2.d Se han definido los campos clave en las tablas.
- RA2.e Se han implantado las restricciones reflejadas en el diseño lógico.
- RA2.f Se han creado vistas.
- RA2.g Se han creado los usuarios y se les han asignado privilegios.
- RA2.h Se han utilizado asistentes, herramientas gráficas y los lenguajes de definición y control de datos.
RA6 Diseña modelos relacionales normalizados interpretando diagramas entidad/relación. 2 CE
- RA6.a Se han utilizado herramientas gráficas para representar el diseño lógico.
- RA6.f Se han aplicado reglas de integridad.
Temporalización
La unidad ocupa 17 horas de aula (9 de teoría y 8 de práctica).
| Sesión | Horas | Tipo | Contenido | Dónde |
|---|---|---|---|---|
| 1 | 1 | Teoría | SQL y Oracle. Almacenamiento de la información | §1 y §2 |
| 2 | 2 | Teoría | Tipos de datos de Oracle | §3 · calculadora de NUMBER(p, s) |
| 3 | 2 | Teoría | CREATE TABLE y restricciones de integridad | §4 y §5 · constructor de CREATE TABLE |
| 4 | 2 | Práctica | Primeras tablas y restricciones en Oracle | Práctica 5.1 |
| 5 | 2 | Práctica | Del diagrama de Chen al DDL | Práctica 5.2 |
| 6 | 1 | Teoría | Modificar y eliminar la estructura (ALTER, DROP) | §6 |
| 7 | 1 | Práctica | Evolución del esquema con ALTER | Práctica 5.5 |
| 8 | 1 | Teoría | Secuencias, identidad, índices y vistas | §7, §8 y §9 |
| 9 | 1 | Práctica | Índices, vistas y secuencias en EduGest | Práctica 5.6 |
| 10 | 2 | Teoría | Usuarios, roles y privilegios. Diccionario de datos y herramientas | §10 a §12 · taller de privilegios |
| 11 | 1 | Práctica | Usuarios, roles y privilegios en EduGest | Práctica 5.7 |
| 12 | 1 | Práctica | Implementación de EduGest | Proyecto EduGest-5 |
En esta unidad pasas del papel al SGBD. Ejecuta cada sentencia mientras lees: un
CREATE TABLEque no has probado es solo una hipótesis. Los widgets interactivos simulan el comportamiento de Oracle con fines didácticos, pero no sustituyen a un SGBD real.
Objetivos de aprendizaje
Al terminar esta unidad serás capaz de:
- Explicar cómo almacena Oracle la información (bloques, segmentos, tablespaces).
- Elegir el tipo de datos adecuado para cada columna.
- Crear tablas con todas las restricciones del diseño lógico: claves primarias, ajenas y alternativas,
NOT NULLyCHECK. - Modificar y eliminar objetos de forma segura.
- Crear secuencias, columnas identidad, índices y vistas.
- Crear usuarios y roles, y asignar privilegios aplicando el principio de mínimo privilegio.
- Consultar el diccionario de datos para comprobar lo que has creado.
- Usar asistentes y herramientas gráficas sin depender de ellos.
Curiosidad ¿De dónde viene el nombre «Oracle»?
Antes de ser una empresa de bases de datos, Larry Ellison, Bob Miner y Ed Oates trabajaron en un proyecto para la CIA con el nombre en clave Oracle. Cuando fundaron su propia compañía en 1977 (entonces Software Development Laboratories) reutilizaron el nombre para el producto.
1. SQL y Oracle
1.1 Sublenguajes de SQL
| Sublenguaje | Sentencias | Para qué | Unidad |
|---|---|---|---|
| DDL | CREATE, ALTER, DROP, TRUNCATE, RENAME, COMMENT | Definir la estructura | UD05 |
| DCL | GRANT, REVOKE | Controlar el acceso | UD05 |
| DML | SELECT, INSERT, UPDATE, DELETE, MERGE | Consultar y modificar datos | UD06 a UD08 |
| TCL | COMMIT, ROLLBACK, SAVEPOINT | Controlar transacciones | UD08 |
En Oracle, cada sentencia DDL ejecuta un
COMMITimplícito antes y después de ejecutarse. Si tenías cambios de datos pendientes y lanzas unCREATE TABLE, esos cambios quedan confirmados y ya no podrás deshacerlos conROLLBACK.
1.2 SQL estándar frente a dialectos
SQL es un estándar ISO/IEC 9075, pero cada SGBD implementa una parte y añade extensiones. Por eso un script de MySQL no suele funcionar en Oracle sin cambios:
1.3 Reglas de escritura en Oracle
- Las palabras reservadas y los identificadores no distinguen mayúsculas:
CREATE TABLE Alumnocrea la tablaALUMNO. Oracle guarda los nombres en mayúsculas en el diccionario. - Si escribes un identificador entre comillas dobles (
"Alumno"), Oracle respeta mayúsculas y espacios, y tendrás que usar siempre las comillas. Evítalo. - Los identificadores pueden tener hasta 128 bytes (desde Oracle 12.2), empiezan por letra y pueden contener letras, números,
_,$y#. - Cada sentencia termina en
;. Los bloques PL/SQL (UD09) terminan además con/en una línea. - Comentarios:
-- hasta el final de la líneay/* de varias líneas */. - Las cadenas van entre comillas simples:
'DAM'. Para incluir una comilla, se duplica:'Sant Joan d''Alacant'.
1.4 Usuario y esquema
En Oracle, un esquema es el conjunto de objetos (tablas, vistas, índices…) que pertenecen a un usuario, y tiene su mismo nombre. Al conectarte como EDUGEST y crear la tabla ALUMNO, su nombre completo es EDUGEST.ALUMNO. Otro usuario con permiso la consultaría así:
SELECT * FROM edugest.alumno;2. Formato de almacenamiento de la información
El criterio RA2.a pide analizar cómo se guarda la información. Oracle organiza el almacenamiento en dos niveles:
flowchart LR
subgraph Lógico
TS[Tablespace USERS] --> SEG[Segmento<br/>tabla ALUMNO]
SEG --> EXT[Extensiones]
EXT --> BLK[Bloques de datos<br/>8 KB]
end
subgraph Físico
DF[(Ficheros de datos .dbf)] --> OSB[Bloques del<br/>sistema operativo]
end
TS -.se guarda en.-> DF
BLK -.ocupan.-> OSB| Estructura | Qué es |
|---|---|
| Bloque de datos | La unidad mínima de lectura y escritura (normalmente 8 KB). Contiene varias filas |
| Extensión (extent) | Conjunto de bloques contiguos que se asigna de una vez |
| Segmento | Todo el espacio de un objeto: una tabla, un índice… |
| Tablespace | Contenedor lógico de segmentos. USERS es el de los datos de usuario; SYSTEM y SYSAUX, los del diccionario |
| Fichero de datos | Fichero físico del sistema operativo donde se guarda un tablespace |
Cada fila tiene una dirección física única, el ROWID, que indica el fichero, el bloque y la posición dentro del bloque. Es la forma más rápida de localizar una fila y la que usan internamente los índices.
SELECT ROWID, nombre FROM alumno FETCH FIRST 3 ROWS ONLY;Una tabla normal de Oracle es una tabla montón (heap): las filas se guardan donde hay espacio libre, sin ningún orden. Por eso una consulta sin
ORDER BYpuede devolver las filas en cualquier orden, y ese orden puede cambiar.
Curiosidad En Oracle, la cadena vacía es NULL
A diferencia del estándar SQL, Oracle trata '' (cadena de longitud cero) como NULL. Por eso WHERE nombre = '' nunca devuelve filas y hay que escribir WHERE nombre IS NULL.
3. Tipos de datos
Elegir bien el tipo de cada columna (RA2.c) evita errores, ahorra espacio y permite que el SGBD valide los datos.
3.1 Tipos principales de Oracle
| Categoría | Tipo | Descripción | Ejemplo de uso |
|---|---|---|---|
| Texto | VARCHAR2(n) | Texto de longitud variable, hasta n bytes (máx. 4000; 32767 con MAX_STRING_SIZE=EXTENDED) | nombre, email |
CHAR(n) | Texto de longitud fija: se rellena con espacios | dni, códigos de longitud fija | |
NVARCHAR2(n) | Texto Unicode en el juego de caracteres nacional | Raramente necesario con AL32UTF8 | |
CLOB | Texto muy largo (gigabytes) | observaciones, documentos | |
| Numérico | NUMBER(p, s) | Número exacto con p dígitos en total y s decimales | importes, notas, cantidades |
NUMBER | Sin precisión: cualquier número | evitarlo en columnas de negocio | |
INTEGER | Sinónimo de NUMBER(38) | contadores | |
BINARY_DOUBLE | Coma flotante IEEE 754 | cálculos científicos | |
| Fecha y hora | DATE | Fecha y hora (hasta segundos) | fecha de nacimiento, de matrícula |
TIMESTAMP(n) | Fecha y hora con fracciones de segundo | registros de auditoría | |
TIMESTAMP WITH TIME ZONE | Incluye la zona horaria | aplicaciones internacionales | |
INTERVAL DAY TO SECOND | Duración | tiempo de una tarea | |
| Lógico | BOOLEAN | TRUE, FALSE o NULL (desde 23ai) | activo, justificada |
| Binario | BLOB, RAW(n) | Datos binarios | fotografías, hashes |
| Otros | JSON | Documento JSON nativo (desde 21c) | datos semiestructurados |
VECTOR | Vectores para búsqueda por similitud (desde 23ai) | aplicaciones de IA |
3.2 Precisión y escala de NUMBER
NUMBER(p, s): p es el número total de dígitos significativos y s cuántos de ellos van tras la coma.
| Declaración | Rango admitido | Valor insertado | Valor guardado |
|---|---|---|---|
NUMBER(4,2) | -99,99 a 99,99 | 7.256 | 7,26 (redondea) |
NUMBER(4,2) | 123.5 | Error ORA-01438 | |
NUMBER(5) | -99999 a 99999 | 12.7 | 13 |
NUMBER(8,2) | hasta 999 999,99 | 1520.5 | 1520,50 |
3.3 Criterios para elegir el tipo
- ¿Se opera con él? Si se suma o se compara numéricamente, es
NUMBER. Si no (DNI, teléfono, código postal), es texto:'03690'perdería el cero inicial como número. - ¿Tiene longitud fija?
CHARsolo si siempre ocupa lo mismo (DNI:CHAR(9)). En el resto,VARCHAR2. - ¿Necesita decimales exactos? El dinero se guarda siempre en
NUMBER(p, s), nunca en coma flotante. - ¿Es una fecha? Usa
DATEoTIMESTAMP, nunca texto: así puedes ordenar, comparar y calcular. - Dimensiona con margen razonable, sin exagerar:
VARCHAR2(4000)para un nombre dificulta la validación y la lectura del diseño.
3.4 Equivalencias con otros SGBD
| Concepto | Oracle | MySQL / MariaDB | PostgreSQL | SQL Server |
|---|---|---|---|---|
| Texto variable | VARCHAR2(n) | VARCHAR(n) | VARCHAR(n) | VARCHAR(n) |
| Entero | NUMBER(10) | INT | INTEGER | INT |
| Decimal exacto | NUMBER(p,s) | DECIMAL(p,s) | NUMERIC(p,s) | DECIMAL(p,s) |
| Fecha sin hora | DATE (incluye hora) | DATE | DATE | DATE |
| Autoincremento | IDENTITY o secuencia | AUTO_INCREMENT | IDENTITY o SERIAL | IDENTITY |
| Lógico | BOOLEAN (23ai) | BOOLEAN (= TINYINT(1)) | BOOLEAN | BIT |
En Oracle la cadena vacía
''esNULL.INSERT INTO alumno (..., email) VALUES (..., '')guarda unNULL, y la condiciónemail = ''nunca es verdadera. En MySQL y PostgreSQL la cadena vacía yNULLson cosas distintas. Es una de las diferencias que más errores provoca al migrar.
El tipo
DATEde Oracle siempre guarda la hora.SYSDATEdevuelve fecha y hora actuales. Si comparasfecha_matricula = DATE '2025-09-15'y la fila se insertó conSYSDATE, no coincidirá porque la hora no es 00:00:00. Lo trataremos en la UD06.
Calculadora de NUMBER(p, s)
Prueba qué valores admite una columna y cómo los redondea Oracle. Observa lo que ocurre cuando la escala es negativa o cuando el valor excede la precisión.
4. Creación de tablas: CREATE TABLE
4.1 Finalidad y sintaxis
CREATE TABLE crea una tabla vacía con sus columnas y restricciones.
CREATE TABLE [esquema.]nombre_tabla (
columna tipo [DEFAULT valor] [restricciones_de_columna],
columna tipo ...,
[restricciones_de_tabla]
);4.2 Ejemplo sencillo, elemento a elemento
Oracle 26aiCREATE TABLE ciclo (
cod_ciclo VARCHAR2(5) CONSTRAINT pk_ciclo PRIMARY KEY,
nombre VARCHAR2(100) NOT NULL,
grado VARCHAR2(8) DEFAULT 'SUPERIOR' NOT NULL,
horas_totales NUMBER(4)
);| Elemento | Significado |
|---|---|
CREATE TABLE ciclo | Crea una tabla llamada CICLO en el esquema del usuario conectado |
cod_ciclo VARCHAR2(5) | Columna de texto variable de hasta 5 bytes |
CONSTRAINT pk_ciclo PRIMARY KEY | Restricción con nombre PK_CICLO: cod_ciclo es la clave primaria (única y no nula) |
NOT NULL | La columna es obligatoria |
DEFAULT 'SUPERIOR' | Valor que se usa si en el INSERT no se indica esta columna |
NUMBER(4) | Número entero de hasta 4 dígitos. Sin NOT NULL, admite nulos |
Comprueba el resultado con la orden DESC del cliente:
SQL> DESC ciclo
Name Null? Type
-------------- -------- -------------
COD_CICLO NOT NULL VARCHAR2(5)
NOMBRE NOT NULL VARCHAR2(100)
GRADO NOT NULL VARCHAR2(8)
HORAS_TOTALES NUMBER(4)4.3 Restricciones de columna y de tabla
Una restricción puede escribirse junto a la columna o al final, como un elemento más de la tabla. Las restricciones que afectan a varias columnas (una clave primaria compuesta, un UNIQUE de dos columnas o un CHECK que compara dos columnas) solo pueden escribirse al final.
CREATE TABLE imparte (
id_modulo NUMBER(5),
cod_grupo VARCHAR2(10),
curso_academico CHAR(7),
id_profesor NUMBER(5) NOT NULL,
horas_semanales NUMBER(2) NOT NULL,
-- restricciones de tabla
CONSTRAINT pk_imparte PRIMARY KEY (id_modulo, cod_grupo, curso_academico),
CONSTRAINT ck_imparte_horas CHECK (horas_semanales BETWEEN 1 AND 12)
);4.4 Valores por defecto y columnas especiales
| Cláusula | Efecto | Ejemplo |
|---|---|---|
DEFAULT expr | Se usa si la columna no aparece en el INSERT | fecha_alta DATE DEFAULT SYSDATE |
DEFAULT ON NULL expr | Se usa también si se inserta explícitamente NULL | convocatoria NUMBER(1) DEFAULT ON NULL 1 |
GENERATED ALWAYS AS IDENTITY | Oracle genera el valor; no se puede insertar uno propio | id NUMBER GENERATED ALWAYS AS IDENTITY |
GENERATED BY DEFAULT ON NULL AS IDENTITY | Oracle genera el valor si no se indica o si es NULL | Usado en ALUMNO de EduGest |
GENERATED ALWAYS AS (expr) VIRTUAL | Columna virtual: se calcula, no se almacena | total NUMBER GENERATED ALWAYS AS (cantidad * precio) VIRTUAL |
5. Restricciones de integridad
Las restricciones implantan en la base de datos las reglas del diseño lógico (RA2.d, RA2.e, RA6.f). El SGBD rechaza cualquier operación que las incumpla, venga de la aplicación que venga.
5.1 Resumen de restricciones
| Restricción | Garantiza | Prefijo del nombre | Error si se incumple |
|---|---|---|---|
NOT NULL | La columna tiene valor | nn_ | ORA-01400 cannot insert NULL |
PRIMARY KEY | Identificación única y no nula de cada fila | pk_ | ORA-00001 unique constraint violated |
UNIQUE | No hay valores repetidos (admite varios NULL) | uq_ | ORA-00001 |
FOREIGN KEY | El valor existe en la tabla referenciada | fk_ | ORA-02291 parent key not found / ORA-02292 child record found |
CHECK | Se cumple una condición sobre la fila | ck_ | ORA-02290 check constraint violated |
Pon siempre nombre a las restricciones. Si no lo haces, Oracle inventa uno como
SYS_C008123. Cuando un usuario reciba el errorORA-02290: check constraint (EDUGEST.CK_MATRICULA_NOTA) violated, sabrá exactamente qué regla ha incumplido.
5.2 Clave primaria y claves alternativas
CREATE TABLE profesor (
id_profesor NUMBER(5) CONSTRAINT pk_profesor PRIMARY KEY,
dni CHAR(9) CONSTRAINT nn_profesor_dni NOT NULL,
email VARCHAR2(100) NOT NULL,
...
CONSTRAINT uq_profesor_dni UNIQUE (dni),
CONSTRAINT uq_profesor_email UNIQUE (email)
);Una clave candidata no elegida como primaria se implanta como UNIQUE + NOT NULL. Oracle crea automáticamente un índice para cada PRIMARY KEY y cada UNIQUE.
5.3 Claves ajenas
CONSTRAINT fk_matricula_alumno FOREIGN KEY (id_alumno)
REFERENCES alumno (id_alumno)
ON DELETE CASCADE| Componente | Significado |
|---|---|
FOREIGN KEY (id_alumno) | Columna (o columnas) de esta tabla |
REFERENCES alumno (id_alumno) | Tabla y columna referenciadas: deben ser su PRIMARY KEY o un UNIQUE |
ON DELETE CASCADE | Al borrar el alumno, se borran sus matrículas |
ON DELETE SET NULL | Al borrar la fila padre, la columna se pone a NULL |
| (nada) | Se rechaza el borrado del padre si tiene hijos |
- La tabla referenciada debe existir antes. Crea primero las tablas «padre» o añade la clave ajena después con
ALTER TABLE(es lo que hace EduGest con el jefe de departamento, porqueDEPARTAMENTOyPROFESORse referencian mutuamente).- Una clave ajena admite
NULLsalvo que añadasNOT NULL. Una fila con la clave ajena aNULLno se comprueba.- Oracle no crea índices sobre las claves ajenas. Créalos tú (apartado 8).
5.4 Restricciones CHECK
Un CHECK es una condición que debe ser verdadera o desconocida (NULL) para cada fila:
CONSTRAINT ck_matricula_nota CHECK (nota_final BETWEEN 0 AND 10),
CONSTRAINT ck_grupo_turno CHECK (turno IN ('M', 'T')),
CONSTRAINT ck_falta_horas CHECK (horas BETWEEN 1 AND 6),
CONSTRAINT ck_matricula_curso CHECK (REGEXP_LIKE(curso_academico, '^[0-9]{4}-[0-9]{2}$')),
CONSTRAINT ck_reserva_fechas CHECK (fecha_salida > fecha_entrada)Si
nota_finalesNULL, la condiciónnota_final BETWEEN 0 AND 10es desconocida y elCHECKla acepta. Si la columna debe tener valor, añadeNOT NULL.Un
CHECKno puede usar subconsultas, ni consultar otras tablas, ni llamar aSYSDATE. Las reglas que lo necesitan son restricciones no representables (UD03, apartado 6) y se implementan con triggers (UD09).
5.5 Consultar las restricciones en el diccionario
SELECT constraint_name, constraint_type, search_condition, r_constraint_name, delete_rule
FROM user_constraints
WHERE table_name = 'MATRICULA'
ORDER BY constraint_type;
SELECT constraint_name, column_name, position
FROM user_cons_columns
WHERE table_name = 'MATRICULA'
ORDER BY constraint_name, position;constraint_type: P = clave primaria, U = única, R = referencial (clave ajena), C = CHECK (también NOT NULL).
Constructor de CREATE TABLE
Define columnas, tipos y restricciones y observa el script que genera. Las restricciones llevan siempre nombre (pk_, fk_, uq_, ck_, nn_), lo que facilita interpretar los errores de Oracle.
PK: marca varias columnas para una clave primaria compuesta. FK: escribe tabla(columna). CHECK: la condición sin la palabra CHECK.
Cambia al ejemplo MATRICULA y localiza la clave primaria compuesta y las dos claves ajenas. Después elimina una de ellas y razona qué integridad pierdes.
De las reglas de transformación de la UD03 al DDL
En la UD03 diseñaste el esquema relacional sin escribir SQL. Esta tabla traduce cada decisión de diseño a su sentencia en Oracle:
| Decisión de diseño (UD03) | Se implanta en Oracle como |
|---|---|
| Clave primaria (PK) | PRIMARY KEY; si es compuesta, restricción de tabla PRIMARY KEY (col1, col2) |
| Clave alternativa (UK) | UNIQUE, y NOT NULL si el atributo es obligatorio |
| Atributo obligatorio | NOT NULL |
| Regla de fila | CHECK (condición sobre la propia fila) |
| Clave ajena obligatoria (participación mínima 1) | FOREIGN KEY + columna NOT NULL |
| Relación 1:1 con clave ajena | FOREIGN KEY + UNIQUE sobre la clave ajena |
| Borrado en cascada | ON DELETE CASCADE |
| Puesta a nulos | ON DELETE SET NULL (la columna debe admitir NULL) |
| Borrado restringido | no se escribe nada: es el comportamiento por defecto de Oracle |
| Cambio de clave en cascada | No existe ON UPDATE en Oracle: por eso se usan claves primarias estables |
Cuando traduzcas un esquema de la UD03, sigue este orden: primero las tablas sin claves ajenas, después las tablas hijas y, por último, las claves ajenas circulares con
ALTER TABLE.
Curiosidad DDL confirma solo
En Oracle, cada sentencia DDL (CREATE, ALTER, DROP) hace un COMMIT implícito antes y después. No se puede deshacer con ROLLBACK: por eso se prueba primero en un esquema de pruebas.
6. Modificar y eliminar la estructura
6.1 ALTER TABLE
Oracle 26ai-- Añadir columnas (en Oracle no se escribe la palabra COLUMN)
ALTER TABLE alumno ADD (fecha_alta DATE DEFAULT SYSDATE);
-- Cambiar el tipo, el tamaño o la obligatoriedad
ALTER TABLE alumno MODIFY (telefono VARCHAR2(20));
ALTER TABLE alumno MODIFY (localidad NOT NULL); -- falla si hay filas con NULL
-- Renombrar y eliminar columnas
ALTER TABLE alumno RENAME COLUMN telefono TO telefono_movil;
ALTER TABLE alumno DROP COLUMN fecha_alta;
-- Añadir y eliminar restricciones
ALTER TABLE alumno ADD CONSTRAINT ck_alumno_email CHECK (email LIKE '%@%');
ALTER TABLE alumno DROP CONSTRAINT ck_alumno_email;
-- Desactivar temporalmente una restricción (por ejemplo, en una carga masiva)
ALTER TABLE matricula DISABLE CONSTRAINT fk_matricula_modulo;
ALTER TABLE matricula ENABLE CONSTRAINT fk_matricula_modulo;
-- Renombrar una tabla
RENAME alumno_tmp TO alumno_historico;Al activar una restricción, Oracle comprueba todas las filas existentes. Si alguna la incumple, el
ENABLEfalla. ConENABLE NOVALIDATEsolo se comprueban las filas nuevas, pero entonces la tabla puede contener datos incorrectos.
6.2 DROP TABLE, papelera y TRUNCATE
DROP TABLE matricula; -- va a la papelera de reciclaje
FLASHBACK TABLE matricula TO BEFORE DROP; -- la recupera
DROP TABLE matricula PURGE; -- borrado definitivo
DROP TABLE alumno CASCADE CONSTRAINTS; -- borra también las FK que apuntan a ALUMNO
DROP TABLE IF EXISTS alumno_tmp; -- sin error si no existe (23ai y posteriores)
TRUNCATE TABLE falta_asistencia; -- vacía la tabla; no se puede deshacer| Sentencia | Borra | Estructura | ¿Se puede deshacer? |
|---|---|---|---|
DELETE FROM t (DML, UD08) | Filas (todas o algunas) | Se mantiene | Sí, con ROLLBACK |
TRUNCATE TABLE t | Todas las filas | Se mantiene | No (es DDL) |
DROP TABLE t | Tabla y datos | Desaparece | Solo desde la papelera |
DROP TABLE t PURGE | Tabla y datos | Desaparece | No |
TRUNCATEyDROP ... PURGEno se pueden deshacer. En un servidor de producción, antes de ejecutarlos: comprueba a qué base de datos estás conectado, haz una copia de seguridad y, si es posible, que otra persona revise la orden.
6.3 Documentar el diseño con comentarios
COMMENT ON TABLE matricula IS 'Matrícula de un alumno en un módulo para un curso académico';
COMMENT ON COLUMN matricula.nota_final IS 'NULL = sin calificar';
SELECT column_name, comments FROM user_col_comments WHERE table_name = 'MATRICULA';7. Secuencias y columnas identidad
Para generar identificadores artificiales (claves subrogadas) hay dos mecanismos:
Las secuencias no garantizan valores consecutivos: un
ROLLBACK, la caché o un reinicio pueden dejar huecos. Un identificador artificial solo debe ser único, no correlativo. Si el negocio exige números de factura sin huecos, hay que implementarlo de otra forma.
8. Índices
Un índice es una estructura adicional, normalmente un árbol B+, que permite localizar filas sin recorrer toda la tabla, igual que el índice alfabético de un libro.
-- Índice simple sobre una clave ajena
CREATE INDEX ix_alumno_grupo ON alumno (cod_grupo);
-- Índice compuesto: útil para búsquedas por apellidos y nombre
CREATE INDEX ix_alumno_apellidos_nombre ON alumno (apellidos, nombre);
-- Índice único (equivale a la restricción UNIQUE, pero es preferible la restricción)
CREATE UNIQUE INDEX ux_modulo_codigo_ciclo ON modulo (codigo, cod_ciclo);
-- Índice basado en función: búsquedas sin distinguir mayúsculas
CREATE INDEX ix_alumno_email_upper ON alumno (UPPER(email));
DROP INDEX ix_alumno_apellidos_nombre;| Conviene indexar | No conviene indexar |
|---|---|
Claves ajenas (se usan en los JOIN y al borrar en la tabla padre) | Tablas muy pequeñas |
Columnas muy usadas en WHERE con valores muy selectivos | Columnas con pocos valores distintos (turno: M/T) |
| Columnas usadas para ordenar resultados grandes | Columnas que se modifican constantemente |
Un índice acelera las lecturas pero ralentiza las escrituras: cada
INSERT,UPDATEoDELETEtiene que actualizar también todos los índices de la tabla, y además ocupa espacio. Indexar es una decisión de diseño físico: la UD07 enseña a comprobar con el plan de ejecución si un índice se usa.
Laboratorio: ¿cuánto ayuda un índice?
Mueve el deslizador para ver cuántos bloques lee una búsqueda con y sin índice.
Modelo simplificado: 100 filas por bloque, un B-tree con ~200 claves por nodo y acceso a una sola fila por clave única. La barra usa escala logarítmica.
9. Vistas
Una vista es una consulta guardada con nombre que se usa como si fuera una tabla. No almacena datos: cada vez que se consulta, ejecuta su SELECT (RA2.f).
9.1 Para qué sirven
- Seguridad: mostrar solo algunas columnas o filas a ciertos usuarios.
- Simplicidad: ocultar consultas complejas (varias tablas, cálculos).
- Independencia lógica: si cambia la estructura de las tablas, se adapta la vista y las aplicaciones siguen funcionando.
9.2 Creación
-- El profesorado necesita el listado de alumnos, pero no su DNI ni su teléfono
CREATE OR REPLACE VIEW v_alumno_listado AS
SELECT id_alumno, nia, nombre, apellidos, email, cod_grupo
FROM alumno;
-- Vista de solo lectura para tutoría: alumnado de un grupo concreto
CREATE OR REPLACE VIEW v_alumno_1dam AS
SELECT id_alumno, nombre, apellidos, email
FROM alumno
WHERE cod_grupo = '1DAM'
WITH READ ONLY;
-- Vista actualizable que impide «sacar» filas de su ámbito
CREATE OR REPLACE VIEW v_matricula_abierta AS
SELECT id_matricula, id_alumno, id_modulo, curso_academico, nota_final
FROM matricula
WHERE curso_academico = '2026-27'
WITH CHECK OPTION CONSTRAINT ck_v_matricula_abierta;
SELECT * FROM v_alumno_listado WHERE cod_grupo = '2DAW';
DROP VIEW v_alumno_1dam;| Cláusula | Efecto |
|---|---|
OR REPLACE | Si la vista existe, la sustituye sin perder los privilegios concedidos |
WITH READ ONLY | No permite INSERT, UPDATE ni DELETE a través de la vista |
WITH CHECK OPTION | Solo permite insertar o modificar filas que sigan cumpliendo el WHERE de la vista |
Una vista sobre una sola tabla, sin agrupaciones,
DISTINCTni columnas calculadas, suele ser actualizable: unUPDATEsobre la vista modifica la tabla base. Las vistas conJOINsolo lo son parcialmente. Una vista materializada (CREATE MATERIALIZED VIEW) sí almacena el resultado y se refresca periódicamente: es una herramienta de rendimiento para informes.
10. Control de datos: usuarios, privilegios y roles
10.1 El principio de mínimo privilegio
Cada usuario debe tener solo los permisos imprescindibles para su trabajo y solo durante el tiempo que los necesita. Si una aplicación se conecta como administrador y sufre una inyección SQL, el atacante obtiene control total de la base de datos.
flowchart TB
subgraph EDUGEST[Esquema EDUGEST: propietario de las tablas]
T[(Tablas)]
V[(Vistas)]
end
S[rol_secretaria] -->|SELECT, INSERT, UPDATE| T
P[rol_profesorado] -->|SELECT vistas · UPDATE nota_final| V
C[rol_consulta] -->|SELECT vistas| V
u1([sec_ana]) --> S
u2([prof_marta]) --> P
u3([dir_jefatura]) --> C
app([app_edugest]) --> S10.2 Usuarios
Oracle 26ai (conectado como SYSTEM a FREEPDB1)
CREATE USER prof_marta IDENTIFIED BY "Cambiar_2026"
DEFAULT TABLESPACE users
QUOTA 0 ON users -- no podrá crear objetos que ocupen espacio
PASSWORD EXPIRE; -- deberá cambiar la contraseña al entrar
ALTER USER prof_marta IDENTIFIED BY "Nueva_Clave_2026";
ALTER USER prof_marta ACCOUNT LOCK; -- bloquear (baja temporal)
ALTER USER prof_marta ACCOUNT UNLOCK;
DROP USER prof_marta CASCADE; -- CASCADE borra también sus objetos10.3 Privilegios de sistema y de objeto
| Tipo | Qué permite | Ejemplos |
|---|---|---|
| De sistema | Realizar una acción en la base de datos | CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE ANY TABLE, SELECT ANY TABLE |
| De objeto | Realizar una acción sobre un objeto concreto | SELECT, INSERT, UPDATE, DELETE sobre una tabla o vista; EXECUTE sobre un procedimiento; REFERENCES |
-- Privilegio de sistema: poder conectarse
GRANT CREATE SESSION TO prof_marta;
-- Privilegios de objeto (los concede el propietario, EDUGEST, o un administrador)
GRANT SELECT ON edugest.v_alumno_listado TO prof_marta;
GRANT SELECT, UPDATE (nota_final) ON edugest.matricula TO prof_marta; -- solo esa columna
-- Retirar privilegios
REVOKE UPDATE ON edugest.matricula FROM prof_marta;| Opción | Significado | Riesgo |
|---|---|---|
WITH ADMIN OPTION (privilegios de sistema y roles) | El receptor puede conceder el privilegio a otros | Al revocarlo, no se revoca en cascada a quienes lo recibieron |
WITH GRANT OPTION (privilegios de objeto) | El receptor puede conceder el privilegio sobre el objeto | Al revocarlo, sí se revoca en cascada |
Evita los privilegios
ANY(SELECT ANY TABLE,DROP ANY TABLE…): se aplican a todos los esquemas de la base de datos, incluidos los de otras aplicaciones.Desde Oracle 23ai existen los privilegios de esquema, que limitan el
ANYa un esquema concreto:GRANT SELECT ANY TABLE ON SCHEMA edugest TO dir_jefatura;. Incluyen también las tablas que se creen en el futuro en ese esquema.
10.4 Roles
Un rol es un conjunto de privilegios con nombre. Se asignan privilegios al rol y el rol a los usuarios: así, cuando llega una profesora nueva basta con una orden.
CREATE ROLE rol_profesorado;
GRANT CREATE SESSION TO rol_profesorado;
GRANT SELECT ON edugest.v_alumno_listado TO rol_profesorado;
GRANT SELECT, UPDATE (nota_final) ON edugest.matricula TO rol_profesorado;
GRANT SELECT, INSERT, UPDATE ON edugest.falta_asistencia TO rol_profesorado;
GRANT rol_profesorado TO prof_marta;
REVOKE rol_profesorado FROM prof_marta;
DROP ROLE rol_profesorado;| Rol predefinido | Contenido | Uso |
|---|---|---|
CONNECT | CREATE SESSION | Usuarios que solo se conectan |
RESOURCE | Crear tablas, secuencias, procedimientos, triggers, tipos | Heredado de versiones antiguas |
DB_DEVELOPER_ROLE (23ai) | Los privilegios habituales de un desarrollador | Cuentas de desarrollo, como EDUGEST |
DBA | Todos los privilegios de administración | Solo administradores. Nunca para aplicaciones |
10.5 Políticas de contraseñas: perfiles
CREATE PROFILE perfil_personal LIMIT
FAILED_LOGIN_ATTEMPTS 5 -- bloqueo tras 5 intentos fallidos
PASSWORD_LOCK_TIME 1/24 -- durante 1 hora
PASSWORD_LIFE_TIME 180 -- caducidad en días
PASSWORD_REUSE_MAX 5; -- no repetir las 5 últimas
ALTER USER prof_marta PROFILE perfil_personal;10.6 Consultar usuarios y privilegios
| Vista | Información |
|---|---|
USER_SYS_PRIVS, USER_ROLE_PRIVS | Privilegios de sistema y roles del usuario conectado |
USER_TAB_PRIVS | Privilegios de objeto concedidos o recibidos por el usuario |
ROLE_TAB_PRIVS, ROLE_SYS_PRIVS | Privilegios contenidos en los roles |
SESSION_PRIVS, SESSION_ROLES | Privilegios activos en la sesión actual |
DBA_USERS, DBA_ROLE_PRIVS | (Administración) todos los usuarios y sus roles |
10.7 Otras medidas de protección
- Autenticación robusta: contraseñas largas, perfiles con caducidad y bloqueo, y cuentas personales (nada de usuarios compartidos).
- Protección de credenciales: nunca escribas contraseñas en el código fuente ni las subas a Git. Usa variables de entorno o gestores de secretos.
- Conexiones seguras: cifra el tráfico con TLS (en Oracle, Native Network Encryption o TCPS).
- Exposición del servicio: el puerto 1521 no debe estar accesible desde Internet; solo desde los servidores de aplicación.
- Copias de seguridad: Oracle Data Pump (
expdp/impdp) para exportar esquemas y RMAN para copias físicas. Una copia que no se ha probado a restaurar no es una copia. - Datos personales: vistas y privilegios por columna para cumplir la minimización del RGPD (UD01).
Taller de roles y privilegios
Diseña un rol, asígnalo a un usuario y comprueba qué sentencias puede ejecutar. Los errores (ORA-01031, ORA-00942, ORA-01045) son los que devuelve Oracle.
SELECT ANY TABLEyGRANT ... WITH ADMIN OPTIONson privilegios muy amplios. Concédelos solo cuando exista una razón justificada y documentada: el mínimo privilegio es una buena práctica de seguridad y un requisito de protección de datos.
11. Diccionario de datos
El diccionario es el catálogo del SGBD: describe todos los objetos. Es la forma de comprobar lo que se ha creado.
| Prefijo | Muestra | Ejemplo |
|---|---|---|
USER_ | Los objetos de tu esquema | USER_TABLES |
ALL_ | Los objetos a los que tienes acceso | ALL_TABLES |
DBA_ | Todos los objetos (requiere privilegios) | DBA_TABLES |
SELECT table_name FROM user_tables ORDER BY 1;
SELECT column_name, data_type, data_length, data_precision, data_scale, nullable
FROM user_tab_columns WHERE table_name = 'ALUMNO' ORDER BY column_id;
SELECT index_name, index_type, uniqueness FROM user_indexes WHERE table_name = 'ALUMNO';
SELECT view_name, text FROM user_views;
SELECT object_name, object_type, status FROM user_objects ORDER BY object_type;12. Asistentes y herramientas gráficas
El criterio RA2.h pide usar asistentes, herramientas gráficas y los lenguajes DDL y DCL.
| Tarea | En SQL Developer | Lo que debes revisar |
|---|---|---|
| Crear una tabla | Clic derecho en Tablas → Nueva tabla (modo avanzado para restricciones) | Pestaña DDL: el código que se va a ejecutar |
| Ver la estructura | Doble clic sobre la tabla → pestañas Columnas, Restricciones, Índices, DDL | Nombres de las restricciones |
| Crear un usuario | Ventana DBA → Seguridad → Usuarios → Crear | Privilegios mínimos |
| Generar el esquema completo | Data Modeler → modelo relacional → Generar DDL | Orden de creación y nombres |
Usa el asistente para aprender la sintaxis y para tareas puntuales, pero guarda siempre el script SQL que genera. Un script se versiona en Git, se revisa, se puede repetir en otro servidor y documenta exactamente qué se hizo. Un clic, no.
13. Errores frecuentes
| Error | Mensaje | Causa y solución |
|---|---|---|
| Crear una FK hacia una tabla que no existe | ORA-00942 table or view does not exist | Crea antes la tabla padre o añade la FK con ALTER TABLE |
| Clave ajena hacia una columna sin PK/UNIQUE | ORA-02270 no matching unique or primary key | La columna referenciada debe ser PK o UNIQUE |
| Tipos distintos entre FK y PK | Funciona, pero provoca conversiones y errores | Declara la FK con el mismo tipo y tamaño que la PK |
| Borrar una tabla referenciada | ORA-02449 unique/primary keys referenced by foreign keys | DROP TABLE ... CASCADE CONSTRAINTS o borra antes las hijas |
Usar ADD COLUMN | ORA-00904 invalid identifier | En Oracle es ALTER TABLE t ADD (col tipo) |
| Nombre de restricción repetido | ORA-02264 name already used by an existing constraint | Los nombres de restricción son únicos en todo el esquema |
Cadena vacía en una columna NOT NULL | ORA-01400 | En Oracle '' es NULL |
14. Resumen
- El DDL define la estructura y el DCL controla el acceso. En Oracle, cada sentencia DDL confirma la transacción en curso.
- Oracle almacena las tablas en segmentos dentro de tablespaces, en bloques de datos; cada fila tiene un
ROWID. - Elige los tipos por su uso:
VARCHAR2,CHAR,NUMBER(p,s),DATE/TIMESTAMPy, desde 23ai,BOOLEAN. En Oracle,''esNULL. - Implanta todas las restricciones del diseño con nombre:
PRIMARY KEY,UNIQUE,FOREIGN KEY,NOT NULLyCHECK. ALTER TABLEmodifica la estructura;DROPyTRUNCATEson destructivos.- Las columnas identidad y las secuencias generan claves artificiales; los índices aceleran las búsquedas a cambio de escrituras más lentas.
- Las vistas simplifican y protegen el acceso. Los usuarios, privilegios y roles aplican el principio de mínimo privilegio.
- El diccionario de datos permite comprobar todo lo creado.