MANUAL DE REPASO
SQL :: FLOTA ESPACIAL

Guia tactica para sustentacion. Modelo relacional, MySQL 8, programacion de servidor y patrones de consulta.

SISTEMA OPERATIVO
00
Mapa de la base de datos
Estructura general que tienes que tener en la cabeza

Tu base tiene 12 tablas. Antes de hablar de SQL, memoriza este mapa porque toda consulta sale de aqui:

imperio
PK codigo_galactico
nombre
temperatura_promedio
planeta
PK nombre_cientifico
poblacion_total
coordenadas_galacticas
nombre_vulgar
FK imperio_codigo
montania
PK id_montania
nombre
altura
FK planeta_cientifico
capitan
PK id_capitan
nombre
FK imperio_codigo
FK planeta_nacimiento
flota
PK codigo_galactico
destino
FK imperio_codigo
mision
PK id_mision
nombre
flota_mision
PKFK flota_codigo
PKFK mision_id
nave
PK id_nave
UK codigo_nave
velocidad_maxima
energia_acumulada
FK flota_codigo
FKUK capitan_id
maniobra
PK nombre
consumo_energia
nave_maniobra
PKFK id_nave
PKFK nombre_maniobra
raza
PK nombre_cientifico
habilidad
PK id_habilidad
frase
FK raza_nombre
raza_planeta
PKFK raza_nombre
PKFK planeta_nombre
porcentaje_poblacion
Como leer el diagrama
PK = Primary Key (clave primaria, identifica cada fila).
FK = Foreign Key (apunta a la PK de otra tabla).
UK = Unique Key (no se puede repetir).
Las tablas en amarillo son tablas intermedias que resuelven relaciones muchos-a-muchos.
01
Conceptos clave
Vocabulario que debes dominar
CONCEPTO
MER
Modelo Entidad-Relacion. Diagrama conceptual con entidades (rectangulos), relaciones (rombos) y atributos (ovalos). Es el "plano" antes de construir.
CONCEPTO
MR
Modelo Relacional. La traduccion del MER a tablas con sus PK y FK. Es el paso intermedio entre el dibujo y el codigo SQL real.
CONCEPTO
DDL
Data Definition Language. Comandos que definen estructura: CREATE, ALTER, DROP. Crean o modifican tablas.
CONCEPTO
DML
Data Manipulation Language. Comandos que manipulan datos: INSERT, UPDATE, DELETE, SELECT. Trabajan sobre el contenido.
CONCEPTO
PK
Primary Key. Una o varias columnas que identifican unicamente cada fila. No se repiten, no son NULL. Solo una PK por tabla.
CONCEPTO
FK
Foreign Key. Columna que apunta a la PK de otra tabla. Garantiza integridad referencial: no puedes referenciar lo que no existe.
CONCEPTO
Cardinalidad
Cuantos elementos de una entidad se relacionan con cuantos de otra. Tipos: 1:1, 1:N, N:M.
CONCEPTO
Normalizacion
Proceso de organizar datos para evitar redundancia. 1FN (atomicos), 2FN (sin dependencias parciales), 3FN (sin dependencias transitivas).
CONCEPTO
InnoDB
Motor de almacenamiento de MySQL. Soporta transacciones, FKs e integridad referencial. Es el motor de tus tablas.

Cardinalidades en tu modelo

RelacionCardinalidadComo se ve en tablas
imperio ↔ flota1:NFK imperio_codigo en flota
flota ↔ nave1:NFK flota_codigo en nave
nave ↔ capitan1:1FK capitan_id en nave con UNIQUE
nave ↔ maniobraN:MTabla intermedia nave_maniobra
flota ↔ misionN:MTabla intermedia flota_mision
raza ↔ planetaN:M con atributoTabla raza_planeta con porcentaje_poblacion
raza ↔ habilidad1:NFK raza_nombre en habilidad (atributo multivaluado)
planeta ↔ montania1:NFK planeta_cientifico en montania
02
Tipos de datos
Que usar y por que
TipoCuando usarloEjemplo en tu modelo
INTNumeros enteros normales (hasta 2.147 millones)id_montania, id_mision
BIGINTEnteros muy grandes (billones)poblacion_total (planetas tienen miles de millones)
DECIMAL(p,s)Numeros exactos con decimales. p=total, s=decimalesDECIMAL(5,2) para porcentaje (0-100 con 2 decimales)
VARCHAR(n)Texto variable, max n caracteresVARCHAR(100) para nombres
CHAR(n)Texto FIJO de n caracteresCodigos siempre del mismo largo
TEXTTexto muy largo (sin limite practico)Descripciones extensas
DATE / DATETIMEFechas y fechas con horaNo usado en tu modelo pero es importante saber
BOOLEANVerdadero/falso (en MySQL es TINYINT(1))Flags, activo/inactivo
DECIMAL vs FLOAT (pregunta clasica)
DECIMAL es exacto. Si almacenas 0.10, recuperas 0.10 exacto. Lo usamos para porcentajes, dinero, medidas precisas.
FLOAT es aproximado (representacion binaria). 0.1 + 0.2 puede dar 0.30000000000000004. Por eso NO se usa para porcentajes o dinero.
En tu modelo usamos DECIMAL para temperatura, velocidad, energia, altura y porcentaje. Si te preguntan por que: precision exacta sin errores de redondeo binario.
03
Consultas basicas (DML)
SELECT, INSERT, UPDATE, DELETE

SELECT: la consulta basica

-- Todas las columnas, todas las filas
SELECT * FROM planeta;

-- Solo algunas columnas
SELECT nombre_vulgar, poblacion_total FROM planeta;

-- Con filtro WHERE
SELECT * FROM planeta
WHERE poblacion_total > 1000000000;

-- Ordenado
SELECT * FROM planeta
ORDER BY poblacion_total DESC;

-- Limitar resultados
SELECT * FROM planeta
ORDER BY poblacion_total DESC
LIMIT 3;

Operadores en WHERE

OperadorUsoEjemplo
=IgualdadWHERE imperio_codigo = 'IMP-001'
!= / <>DistintoWHERE nombre <> 'Tierra'
> < >= <=ComparacionWHERE altura >= 5000
BETWEENRango (inclusivo)WHERE poblacion_total BETWEEN 1000 AND 5000
INLista de valoresWHERE imperio_codigo IN ('IMP-001', 'IMP-002')
LIKEPatron de textoWHERE nombre LIKE 'Imperio%'
IS NULLValor nuloWHERE nombre_vulgar IS NULL
AND / OR / NOTCombinacion logicaWHERE x = 1 AND y > 2

INSERT, UPDATE, DELETE

-- Insertar una fila
INSERT INTO imperio (codigo_galactico, nombre, temperatura_promedio)
VALUES ('IMP-007', 'Imperio Borg', 8.50);

-- Insertar varias filas a la vez
INSERT INTO mision (nombre) VALUES
  ('Reconocimiento'),
  ('Sabotaje');

-- Actualizar (siempre con WHERE, sino actualiza TODO)
UPDATE planeta
SET poblacion_total = 9000000000
WHERE nombre_cientifico = 'FM1073';

-- Borrar (siempre con WHERE)
DELETE FROM capitan
WHERE id_capitan = 'CAP-009';
Error mas comun y peligroso
UPDATE o DELETE sin WHERE actualiza/borra TODAS las filas de la tabla. En produccion esto es un desastre. Practica defensiva: escribe primero el WHERE, despues el SET o el FROM.
04
JOINs: combinar tablas
El corazon del SQL relacional

Un JOIN combina filas de dos o mas tablas basandose en una condicion (generalmente la igualdad PK=FK).

TipoQue devuelveCuando usarlo
INNER JOINSolo las filas que coinciden en ambas tablasCuando solo te interesan registros con relacion completa
LEFT JOINTodas las filas de la izquierda + las que coincidan de la derecha (NULL si no)Cuando quieres ver "lo que esta solo en una tabla"
RIGHT JOINIgual que LEFT pero al revesCasi no se usa, mejor invertir las tablas y usar LEFT
CROSS JOINProducto cartesiano (todas las combinaciones)Casi nunca, generalmente es un error

Ejemplos sobre tu modelo

-- INNER JOIN: planetas con su imperio
SELECT p.nombre_vulgar, p.poblacion_total, i.nombre AS imperio
FROM planeta p
INNER JOIN imperio i ON i.codigo_galactico = p.imperio_codigo;

-- LEFT JOIN: TODOS los capitanes, tengan o no nave
SELECT c.nombre, n.codigo_nave
FROM capitan c
LEFT JOIN nave n ON n.capitan_id = c.id_capitan;

-- LEFT JOIN con filtro IS NULL: capitanes SIN nave
SELECT c.nombre
FROM capitan c
LEFT JOIN nave n ON n.capitan_id = c.id_capitan
WHERE n.id_nave IS NULL;

-- Multiples JOINs: nave, su flota, su capitan y su imperio
SELECT
  n.codigo_nave,
  f.codigo_galactico AS flota,
  c.nombre AS capitan,
  i.nombre AS imperio
FROM nave n
INNER JOIN flota f ON f.codigo_galactico = n.flota_codigo
INNER JOIN capitan c ON c.id_capitan = n.capitan_id
INNER JOIN imperio i ON i.codigo_galactico = c.imperio_codigo;

-- JOIN con tabla intermedia (N:M): misiones de cada flota
SELECT f.codigo_galactico, m.nombre AS mision
FROM flota f
INNER JOIN flota_mision fm ON fm.flota_codigo = f.codigo_galactico
INNER JOIN mision m ON m.id_mision = fm.mision_id;
Como pensar un JOIN
1. Que tablas necesito? Identifica los datos que quieres mostrar.
2. Como se conectan? Busca el camino de PK-FK entre ellas.
3. Necesito todos o solo coincidencias? INNER si solo coincidencias, LEFT si quieres incluir "los huerfanos".
4. Usa alias cortos (FROM planeta p) para escribir menos.
05
Agregaciones y GROUP BY
Contar, sumar, promediar

Las funciones de agregacion calculan un valor a partir de muchas filas:

FuncionQue hace
COUNT(*)Cuenta filas (incluso con NULL)
COUNT(columna)Cuenta filas con valor no nulo
SUM(columna)Suma valores numericos
AVG(columna)Promedio
MIN(columna)Valor minimo
MAX(columna)Valor maximo
-- Total de planetas (lo que hace tu funcion total_planetas)
SELECT COUNT(*) FROM planeta;

-- Suma de poblacion de TODOS los planetas
SELECT SUM(poblacion_total) FROM planeta;

-- Planeta mas poblado
SELECT MAX(poblacion_total) FROM planeta;

GROUP BY: agregar por grupos

Cuando quieres un agregado por categoria, usas GROUP BY:

-- Cuantos planetas tiene cada imperio
SELECT imperio_codigo, COUNT(*) AS total_planetas
FROM planeta
GROUP BY imperio_codigo;

-- Poblacion total por imperio
SELECT imperio_codigo, SUM(poblacion_total) AS poblacion
FROM planeta
GROUP BY imperio_codigo;

-- Promedio de energia de las naves por flota
SELECT flota_codigo, AVG(energia_acumulada) AS energia_prom
FROM nave
GROUP BY flota_codigo;

HAVING: filtrar grupos

WHERE filtra filas individuales. HAVING filtra grupos despues de agregar.

-- Imperios con mas de 1 planeta
SELECT imperio_codigo, COUNT(*) AS total
FROM planeta
GROUP BY imperio_codigo
HAVING COUNT(*) > 1;
Orden de ejecucion logico
Una consulta SQL no se ejecuta en el orden que la escribes. El orden logico es:
1. FROM2. WHERE3. GROUP BY4. HAVING5. SELECT6. ORDER BY7. LIMIT.
Por eso no puedes usar un alias del SELECT en el WHERE: cuando se ejecuta el WHERE, el SELECT todavia no paso.
06
Subconsultas
Una consulta dentro de otra
-- Planetas con poblacion mayor al promedio
SELECT nombre_vulgar, poblacion_total
FROM planeta
WHERE poblacion_total > (
  SELECT AVG(poblacion_total) FROM planeta
);

-- Capitanes que NO tienen nave (con NOT IN)
SELECT nombre
FROM capitan
WHERE id_capitan NOT IN (
  SELECT capitan_id FROM nave
);

-- Imperios que tienen al menos un planeta (con EXISTS)
SELECT nombre
FROM imperio i
WHERE EXISTS (
  SELECT 1 FROM planeta p
  WHERE p.imperio_codigo = i.codigo_galactico
);
JOIN vs Subconsulta
Muchas veces se puede hacer lo mismo con JOIN o subconsulta. Reglas:
- JOIN suele ser mas rapido y legible.
- Subconsulta es mas clara cuando es un calculo independiente (como un promedio que filtra).
- EXISTS es ideal para verificar existencia sin traer datos.
07
Funciones, procedimientos y vistas
Programacion del lado del servidor
FUNCTIONPROCEDUREVIEW
DevuelveUn valor escalarNada o varios via OUTUna tabla virtual
Se llama conSELECT mifn()CALL miproc()SELECT * FROM mivista
Modifica datos?NoSiNo (es un SELECT guardado)
Necesita DELIMITERSiSiNo
Tiene BEGIN/ENDSiSiNo
SQL dinamico (PREPARE)NoSiNo

Sintaxis de FUNCTION (lo que hiciste)

DELIMITER $$

CREATE FUNCTION total_planetas()
RETURNS INT
DETERMINISTIC
BEGIN
  DECLARE total INT;
  SELECT COUNT(*) INTO total FROM planeta;
  RETURN total;
END$$

DELIMITER ;

Que es DETERMINISTIC?

Le dice a MySQL que con los mismos parametros de entrada, siempre devolvera el mismo resultado. Es necesario en muchas configuraciones de MySQL (especialmente con replicacion activa).

Sintaxis de PROCEDURE (lo que hiciste)

DELIMITER $$

CREATE PROCEDURE insertar_imperio (
  IN p_codigo VARCHAR(20),
  IN p_nombre VARCHAR(100),
  IN p_temperatura DECIMAL(6,2)
)
BEGIN
  INSERT INTO imperio (codigo_galactico, nombre, temperatura_promedio)
  VALUES (p_codigo, p_nombre, p_temperatura);
END$$

DELIMITER ;

Tipos de parametros

  • IN = entra al procedimiento (lo mas comun)
  • OUT = sale del procedimiento (resultado)
  • INOUT = entra y sale (poco usado)

Sintaxis de VIEW (lo que hiciste)

CREATE VIEW vista_planetas AS
SELECT * FROM planeta
ORDER BY poblacion_total ASC;

-- Usar la vista
SELECT * FROM vista_planetas;
Para que sirve cada uno (resumen pegajoso)
- FUNCTION: "calculame algo". Devuelve un valor.
- PROCEDURE: "haz esto". Ejecuta operaciones (incluyendo modificar datos).
- VIEW: "guardame esta consulta para no repetirla". Es como un SELECT con alias.
08
Integridad y constraints
Como tu modelo evita basura
ConstraintQue garantizaEjemplo en tu modelo
PRIMARY KEYUnicidad e identificacion de la filacodigo_galactico en imperio
FOREIGN KEYIntegridad referencialimperio_codigo en flota
UNIQUENo se repiten valoresnombre_vulgar en planeta
NOT NULLCampo obligatorioCasi todas las columnas
CHECKValidacion de valorporcentaje_poblacion BETWEEN 0 AND 100
DEFAULTValor por defecto si no se especificaPodria usarse en estados, fechas

ON DELETE / ON UPDATE

Cuando defines una FK, decides que pasa si se borra o cambia la fila padre:

AccionComportamientoCuando usarla
RESTRICTNo deja borrar/actualizar si hay hijosEntidades fuertes (imperio, planeta)
CASCADESe propaga el cambio o borradoTablas intermedias N:M, atributos multivaluados
SET NULLPone NULL en los hijos al borrarCuando la relacion es opcional
NO ACTIONSimilar a RESTRICTIgual que RESTRICT en MySQL/InnoDB
Tu modelo usa una mezcla intencional
- ON DELETE RESTRICT en relaciones a entidades fuertes (no borras un imperio si tiene planetas).
- ON DELETE CASCADE en tablas intermedias y atributos multivaluados (si borras una raza, sus habilidades se van con ella, porque no tienen sentido sin la raza).
- ON UPDATE CASCADE en todas, para que si cambia un codigo galactico se propague automaticamente.
09
Cheatsheet rapido
Lo esencial en una sola pantalla
USE basedatos;
Selecciona la base de datos activa
SHOW DATABASES;
Lista todas las bases
SHOW TABLES;
Lista las tablas de la base actual
DESCRIBE tabla;
Estructura de una tabla (columnas, tipos)
SHOW CREATE TABLE t;
DDL completo de una tabla (lo que ves en Workbench)
SHOW PROCEDURE STATUS;
Lista procedimientos almacenados
SHOW FUNCTION STATUS;
Lista funciones almacenadas
DROP TABLE IF EXISTS t;
Borra tabla si existe (sin error si no existe)
DROP FUNCTION IF EXISTS f;
Borra funcion si existe
DROP PROCEDURE IF EXISTS p;
Borra procedimiento si existe
DROP VIEW IF EXISTS v;
Borra vista si existe
ALTER TABLE t ADD col;
Anade columna a tabla existente
TRUNCATE TABLE t;
Borra TODAS las filas (mas rapido que DELETE sin WHERE)
COMMIT; / ROLLBACK;
Confirma o deshace una transaccion
START TRANSACTION;
Inicia una transaccion
10
Posibles preguntas del profesor
Practicate respondiendolas antes
Diferencia entre PRIMARY KEY y UNIQUE
Ambas garantizan unicidad, pero:
- Solo puede haber UNA PRIMARY KEY por tabla. Puede haber varias UNIQUE.
- PRIMARY KEY no acepta NULL. UNIQUE si acepta NULL (uno por columna en MySQL).
- PRIMARY KEY es el identificador "oficial" de la fila.
Por que usaste DECIMAL en lugar de FLOAT?
Porque DECIMAL es exacto y FLOAT es aproximado. Para porcentajes, temperaturas, energias y medidas que requieren precision, FLOAT puede dar errores de redondeo binario (ejemplo: 0.1 + 0.2 = 0.30000000000000004). DECIMAL evita eso.
Por que existen las tablas intermedias?
Porque resuelven relaciones muchos-a-muchos (N:M), que no se pueden representar directamente con una FK. Una flota tiene muchas misiones, y una mision puede ser cumplida por muchas flotas. Por eso necesitamos flota_mision con las dos FKs como PK compuesta.
Por que la PK de nave es id_nave y no codigo_nave?
Porque el enunciado dice que el codigo de la nave es unico dentro de su flota, no globalmente. Es decir, puede existir una nave con codigo N-001 en la flota FLT-A1 y otra con el mismo codigo en FLT-A2. Por eso uso un id sustituto como PK y agrego UNIQUE(flota_codigo, codigo_nave) para la regla de negocio.
Por que habilidad es una tabla aparte?
Porque las habilidades son un atributo multivaluado de raza (una raza tiene varias frases). En modelo relacional, los atributos multivaluados violan la 1FN si se guardan en una sola columna. La solucion es normalizarlos creando una tabla aparte con FK a la entidad original.
Que es la integridad referencial?
Es la garantia de que toda FK apunta a una PK existente. Si una nave dice que pertenece a la flota FLT-A1, esa flota DEBE existir. Las claves foraneas + ON DELETE/UPDATE garantizan esto.
Diferencia entre DELETE y TRUNCATE
- DELETE FROM t WHERE...: borra filas seleccionadas, se puede revertir con ROLLBACK en transaccion, dispara triggers.
- TRUNCATE TABLE t: borra TODAS las filas, mas rapido, no se puede revertir, resetea AUTO_INCREMENT, no dispara triggers.
DELETE es DML, TRUNCATE es DDL.
Cuando usar INNER JOIN vs LEFT JOIN?
- INNER JOIN: cuando solo te interesan registros que tienen relacion en ambas tablas.
- LEFT JOIN: cuando quieres mostrar TODAS las filas de la tabla principal aunque no tengan relacion (con NULL del lado derecho).
Ejemplo: para mostrar capitanes con sus naves uso INNER si solo quiero los que tienen nave; uso LEFT si quiero incluir los que no tienen.
Que es DETERMINISTIC en una funcion?
Es una declaracion que le dice a MySQL que la funcion siempre devuelve el mismo resultado para los mismos parametros de entrada. Esto permite optimizaciones y es necesario cuando hay replicacion binaria activa.
Por que el DELIMITER se cambia a $$ ?
Porque dentro de funciones y procedimientos usamos el ; normalmente para terminar instrucciones internas (como DECLARE, SELECT, INSERT). Si dejamos el delimitador en ;, Workbench interpretaria el primer ; interno como fin del CREATE. Cambiandolo a $$, le decimos "el fin real es $$" y los ; internos se respetan.
Que diferencia hay entre WHERE y HAVING?
- WHERE filtra filas individuales antes de agrupar.
- HAVING filtra grupos despues de agrupar (puede usar funciones de agregacion).
Ejemplo: WHERE poblacion > 1000 filtra planetas individuales; HAVING COUNT(*) > 1 filtra grupos por cantidad de planetas.
Que pasa si borro un imperio con ON DELETE RESTRICT?
MySQL devuelve un error ERROR 1451: Cannot delete or update a parent row: a foreign key constraint fails porque hay flotas, planetas o capitanes que dependen de ese imperio. Para borrarlo, primero hay que borrar (o reasignar) todo lo que apunta a el.
Que es una transaccion?
Un conjunto de operaciones SQL que se ejecutan como una unidad atomica: o se hacen todas, o no se hace ninguna. Se inicia con START TRANSACTION, se confirma con COMMIT, o se deshace con ROLLBACK. InnoDB las soporta, MyISAM no.
Propiedades ACID: Atomicidad, Consistencia, Aislamiento, Durabilidad.
Que es la normalizacion?
Proceso de organizar los datos para evitar redundancia y anomalias. Las tres formas normales basicas:
- 1FN: cada celda contiene un solo valor (atomico). No listas en una columna.
- 2FN: 1FN + cada atributo no clave depende de toda la PK (no parcial).
- 3FN: 2FN + no hay dependencias transitivas (un atributo no depende de otro atributo no clave).
Tu modelo cumple las tres.
11
Como defender tu modelo
Argumentos listos para usar
El argumento general (apreendelo)
"El modelo respeta las claves naturales que el enunciado define como unicas (codigo galactico para imperios y flotas, nombre cientifico para planetas y razas, id de capitan). Los atributos multivaluados (misiones, maniobras, habilidades, montanas) se normalizan en tablas aparte para cumplir 1FN. Las relaciones N:M se resuelven con tablas intermedias. Las restricciones de integridad (PK, FK, UNIQUE, CHECK) garantizan que solo se puedan ingresar datos validos."

Por que cada tabla existe (memoriza esto)

TablaJustificacion
imperioEntidad principal con PK natural (codigo galactico unico)
planetaEntidad con PK natural (nombre cientifico unico) y FK al imperio
montaniaAtributo multivaluado de planeta (cantidad variable por planeta)
capitanEntidad con PK natural (identificacion unica)
flotaEntidad con PK natural (codigo galactico unico)
misionEntidad para resolver atributo multivaluado de flota
flota_misionTabla intermedia para relacion N:M flota-mision
naveEntidad con PK sustituta (porque su codigo solo es unico DENTRO de la flota)
maniobraEntidad con PK natural (el nombre la identifica)
nave_maniobraTabla intermedia para relacion N:M nave-maniobra
razaEntidad con PK natural (nombre cientifico unico)
habilidadAtributo multivaluado de raza (varias frases por raza)
raza_planetaTabla intermedia para N:M con atributo (porcentaje)

Si te preguntan "que mejorarias?"

Respuesta lista para sonar sofisticado:

Mejoras posibles
- Anadir indices en las columnas mas consultadas (foreign keys ya tienen indice automatico, pero campos como nombre_vulgar podrian beneficiarse).
- Anadir auditoria: columnas created_at, updated_at en cada tabla.
- Usar triggers para validaciones complejas o logs automaticos.
- Implementar roles y permisos con GRANT, dando acceso solo a vistas en lugar de tablas base (importante para seguridad).
- Particionado de tablas grandes (no aplica con estos volumenes, pero es bueno mencionarlo).