Tema 8: INSERT, UPDATE, DELETE: el mantra CRUD con cuidado
Identificador: PF-008
XP: 200
Insignia: 🥇 Oro — "Guardián de los datos"
Tier: Aprendiz
Tiempo estimado: 90-120 minutos
Pre-requisitos: PF-007
🖼️ Imagen de inicio del tema

[Ilustración cartoon a color: Moka, personificada como un calpixqui mexica con tocado de plumas y máscara ritual, sostiene una maza ceremonial de obsidiana (símbolo del poder de modificar registros). A su lado, Sofía se cubre los ojos con temor ante un botón gigante de "ejecutar" en una consola. Don Carlos, atrás, le explica a Citlalli que "este es el botón más peligroso de tu carrera". El fondo es un mercado de Tlatelolco con varios altépetl tributarios.]
Pie de imagen: "Con un gran poder viene una gran responsabilidad. INSERT, UPDATE, DELETE pueden modificar tu base para siempre. Antes de ejecutar, piensa dos veces."
🎯 En este tema aprenderás
🏛️ Visión mexica — Por Citlalli
Citlalli: "Un calpixqui mexica tenía tanto poder sobre los tributos que un error podía significar la muerte. Si borraba por accidente el registro de un pueblo completo, ese pueblo podía ser olvidado por el imperio y condenado a tributos imposibles el año siguiente. Por eso los tlatoanis implementaron un sistema de 'doble verificación': el calpixqui ejecutaba la orden, pero el supervisor (huey calpixqui) la revisaba antes de que se volviera permanente.
En bases de datos modernas, ese 'doble verificación' lo implementas tú mismo: ANTES de hacer un UPDATE o DELETE, ejecutas el mismo `SELECT ... WHERE ...` que vas a usar en el UPDATE/DELETE. Si el SELECT te devuelve las filas correctas, ejecutas el UPDATE/DELETE con el mismo WHERE. Si te devuelve las filas incorrectas, ajustas el WHERE antes de ejecutar nada destructivo.
Es el equivalente digital del consejo mexica: 'antes de actuar, mira qué vas a tocar'."
📚 Bloque 1: INSERT INTO — agregar filas
`INSERT` agrega filas nuevas a una tabla. La sintaxis básica:
INSERT INTO clientes (nombre, email, ciudad, pais)
VALUES ('Ximena Hernández', 'ximena.h@example.com', 'Puebla', 'México');Desglose:
- `INSERT INTO clientes` — la tabla destino.
- `(nombre, email, ciudad, pais)` — las columnas que vas a llenar.
- `VALUES (...)` — los valores, en el mismo orden que las columnas.
Don Carlos: Si omites una columna, la base de datos le pone el valor DEFAULT (o NULL si no hay default). Si omites una columna NOT NULL sin default, la query falla con error.
-- Esto funciona: la columna 'activo' toma su default (1)
INSERT INTO clientes (nombre, email) VALUES ('Sin ciudad', 'sinciudad@example.com');-- Esto FALLA si 'nombre' es NOT NULL
INSERT INTO clientes (email) VALUES ('soloemail@example.com');
Insertar múltiples filas a la vez (más eficiente que varios INSERT separados):
INSERT INTO clientes (nombre, email, ciudad) VALUES
('Cliente 1', 'c1@example.com', 'CDMX'),
('Cliente 2', 'c2@example.com', 'Guadalajara'),
('Cliente 3', 'c3@example.com', 'Monterrey');📚 Bloque 2: UPDATE — modificar filas existentes
`UPDATE` cambia valores de filas que ya existen.
UPDATE clientes
SET telefono = '55-1234-9999', ciudad = 'CDMX'
WHERE id = 1;SIEMPRE con WHERE. Si lo ejecutas sin WHERE, modificas TODAS las filas de la tabla. Eso es un desastre.
El patrón seguro de 3 pasos:
-- Paso 1: ver qué filas vas a afectar
SELECT id, nombre, telefono FROM clientes WHERE ciudad = 'Querétaro';-- Paso 2: si el resultado es correcto, ejecutar el UPDATE con el MISMO WHERE
UPDATE clientes SET telefono = 'NUEVO' WHERE ciudad = 'Querétaro';
Moka: "Si tu empresa tiene un ambiente de 'staging' (réplica de producción), prueba primero ahí. Si tu UPDATE falla en staging con 1 millón de filas, el problema se ve en staging, no en producción. El staging es tu 'simulacro de combate'."
📚 Bloque 3: DELETE — borrar filas (con cuidado)
`DELETE` elimina filas de una tabla.
DELETE FROM clientes WHERE id = 50;REGLA SAGRADA DEL DBA: si ejecutas `DELETE FROM clientes;` sin WHERE, se borran TODOS los clientes de la tabla. La base de datos NO te pide confirmación. El comando se ejecuta.
Don Carlos (con cara seria): "En 22 años de carrera, he visto juniors perder tablas enteras por un DELETE sin WHERE. Una vez, un becario ejecutó `DELETE FROM orders` en producción, sin WHERE, antes de agregar el WHERE. La tabla tenía 2 millones de pedidos. Se perdieron 6 horas de datos hasta que se restauró del backup. Aprendí de esa: ahora SIEMPRE pruebo con SELECT primero."
Patrón seguro (igual que con UPDATE):
-- Paso 1: ver qué filas vas a borrar
SELECT FROM clientes WHERE fecha_registro < '2020-01-01';-- Paso 2: si la lista es correcta, ejecutar el DELETE
DELETE FROM clientes WHERE fecha_registro < '2020-01-01';
Moka: "Si quieres estar SEGURO seguro, envuelve tu DELETE en una transacción con ROLLBACK preparado. Eso lo verás en el Tema 20 (Transacciones)."
📚 Bloque 4: DROP vs DELETE — no los confundas
| Comando | Qué hace | Reversible | |---|---|---| | `DELETE FROM tabla WHERE ...` | Borra FILAS específicas | Sí, con backup o transacción | | `TRUNCATE TABLE tabla` | Borra TODAS las filas (DDL) | No, pero más rápido que DELETE | | `DROP TABLE tabla` | Borra la TABLA ENTERA (estructura + datos) | No, salvo con backup | | `DROP DATABASE nombre` | Borra la BASE DE DATOS ENTERA | No, salvo con backup |
Don Carlos: "La diferencia entre `DELETE` y `DROP` es la diferencia entre 'borrar una entrada de un cuaderno' y 'quemar el cuaderno entero'. Si no entiendes la diferencia, no toques la base de datos en producción."
📚 Bloque 5: La regla de oro del DBA junior
REGLA 1: Nunca ejecutes `UPDATE` o `DELETE` sin `WHERE`.>
REGLA 2: Antes de ejecutar `UPDATE` o `DELETE`, ejecuta el `SELECT` con el mismo `WHERE` y verifica que devuelve las filas correctas.>
REGLA 3: Si tu `UPDATE` o `DELETE` afecta más filas de las esperadas, abortás inmediatamente (Ctrl+C en la terminal, o "Stop query" en DBeaver).>
REGLA 4: En producción, haz SIEMPRE backup antes de cualquier UPDATE/DELETE masivo.>
REGLA 5: Si dudas, pregunta a un senior. Nadie se muere por hacer una pregunta, pero muchos han muerto (figurativamente) por un DELETE sin WHERE.
Citlalli: "Estas reglas son las mismas que aplicaban los tlacuilos mexicas al modificar los códices. Los códices eran sagrados. Un error de un tlacuilo era penado con la muerte. En tu versión moderna, el equivalente no es la muerte física, pero sí la muerte profesional. Cuida tu base de datos como un tlacuilo cuidaba sus códices."
📚 Bloque 6: INSERT con SELECT — poblar tablas rápido
Hay una forma elegante de INSERT que usa SELECT como fuente: INSERT ... SELECT.
-- Crear una tabla de "clientes_vip" con los clientes de CDMX
CREATE TABLE clientes_vip (
id INT PRIMARY KEY,
nombre VARCHAR(100),
email VARCHAR(150),
fecha_registro DATE
);-- Poblar con SELECT
INSERT INTO clientes_vip (id, nombre, email, fecha_registro)
SELECT id, nombre, email, fecha_registro
FROM clientes
WHERE ciudad = 'Ciudad de México' AND activo = 1;
Sofía pregunta: ¿Para qué sirve esto?
Don Carlos: "Tres usos comunes: 1) crear tablas de respaldo, 2) poblar tablas de staging para pruebas, 3) crear tablas agregadas (como 'clientes_vip') que consultas frecuentemente. En el Tema 13 verás las 'vistas' que es otra forma de hacer esto sin duplicar datos."
🤖 AI Mission — "El detective del WHERE"
Misión 8.1: Pídele a la IA:
"Soy DBA junior. Voy a ejecutar este UPDATE en mi base de pruebas: `UPDATE productos SET precio = 999 WHERE nombre LIKE '%Laptop%';`. Antes de ejecutarlo, dame 3 cosas que debería verificar para asegurarme de que voy a modificar exactamente las filas correctas."
Misión 8.2: Pídele a la IA:
"¿Qué es mejor para borrar muchos datos: DELETE con WHERE o TRUNCATE TABLE? Explica las diferencias y cuándo usar cada uno."
⚠️ Errores típicos del principiante
🧪 LAB 8.1 — "Patrón seguro: SELECT, verificar, ejecutar"
Objetivo: practicar el patrón seguro de UPDATE en tu base de datos de prueba.
Materiales: base `tienda_tlalli` cargada en MySQL o PostgreSQL.
Instrucciones: para cada paso, ejecuta el SELECT primero, verifica el resultado, luego ejecuta el UPDATE.
Paso 1 — Sube el precio de todos los productos de la categoría "Ollas y sartenes" (id=18) en 10%.
-- 1. Ver qué se va a modificar
SELECT nombre, precio FROM productos WHERE categoria_id = 18;
-- 2. UPDATE
UPDATE productos SET precio = precio 1.10 WHERE categoria_id = 18;
-- 3. Verificar
SELECT nombre, precio FROM productos WHERE categoria_id = 18;Paso 2 — Desactiva (activo=0) a todos los clientes que NO tengan email.
SELECT nombre, email, activo FROM clientes WHERE email IS NULL OR email = '';
UPDATE clientes SET activo = 0 WHERE email IS NULL OR email = '';
SELECT nombre, email, activo FROM clientes WHERE activo = 0;Paso 3 — Corrige el email de un cliente que tiene un typo. Cliente id=1, su email debería ser `sofia.hdz@example.com`.
SELECT id, nombre, email FROM clientes WHERE id = 1;
UPDATE clientes SET email = 'sofia.hdz@example.com' WHERE id = 1;
SELECT id, nombre, email FROM clientes WHERE id = 1;Paso 4 — Inserta un cliente nuevo: tu propio nombre, con email ficticio.
INSERT INTO clientes (nombre, email, ciudad, pais)
VALUES ('[Tu nombre aquí]', 'tu.email@example.com', 'Tu ciudad', 'México');
SELECT FROM clientes WHERE email = 'tu.email@example.com';Paso 5 — Borra las reseñas con calificacion = 1 (la peor).
-- MUY IMPORTANTE: primero verifica CUÁLES se van a borrar
SELECT FROM resenas WHERE calificacion = 1;
-- Si te parece bien, ejecuta el DELETE
DELETE FROM resenas WHERE calificacion = 1;
-- Verifica que ya no están
SELECT COUNT() FROM resenas WHERE calificacion = 1;
-- Debería devolver 0Verificación: cada paso debe ejecutarse sin error. Después del paso 5, ya no hay reseñas con calificación 1.
🧪 LAB 8.2 — "Simulacro de desastre controlado"
Objetivo: practicar qué hacer cuando accidentalmente ejecutas un UPDATE/DELETE sin WHERE.
Materiales: base `tienda_tlalli`.
Instrucciones (en tu base de prueba, NO en producción):
Paso 1 — Ejecuta por accidente `UPDATE productos SET precio = 1;` (sin WHERE).
UPDATE productos SET precio = 1;
¡PÁNICO! ¿Qué pasó? Todos los productos ahora cuestan $1.Paso 2 — Recupera los precios haciendo ROLLBACK si estás en una transacción, o restaurando del backup si no.
-- Si estás en psql/mysql y la operación fue reciente, intenta:
ROLLBACK;-- Si no funciona, restaura del backup que hiciste en el Tema 4:
-- mysql -u root tienda_tlalli < tienda_tlalli_backup_2026-XX-XX.sql
Paso 3 — Reflexión: anota en tu cuaderno qué sentiste cuando viste que tu UPDATE había afectado todas las filas. Esa sensación es tu mejor maestra.
Moka: "Este ejercicio es incómodo pero NECESARIO. La próxima vez que tengas la tentación de ejecutar un UPDATE sin WHERE en producción, vas a recordar este momento y tu mano se va a detener."
📝 Quest 8 — Preguntas de opción múltiple
Pregunta 1. ¿Cuál es la sintaxis correcta para insertar una fila?
A) `INSERT clientes VALUES (...)` B) `INSERT INTO clientes VALUES (...)` C) `ADD INTO clientes (...) VALUES (...)` D) `INSERT ROW INTO clientes (...)`
Pregunta 2. ¿Qué pasa si ejecutas `UPDATE productos SET precio = 0;` sin WHERE?
A) Solo se actualiza la primera fila. B) Se te pide confirmación. C) Todas las filas de la tabla se actualizan a precio = 0. D) La operación falla por seguridad.
Pregunta 3. ¿Cuál es la diferencia entre DELETE y DROP?
A) DELETE es para filas, DROP es para tablas o bases de datos. B) DELETE borra la base, DROP borra una tabla. C) No hay diferencia. D) DELETE es más rápido que DROP.
Pregunta 4. ¿Qué deberías hacer ANTES de ejecutar un UPDATE/DELETE en producción?
A) Nada, los motores de BD tienen protección automática. B) Ejecutar el mismo SELECT con el WHERE y verificar el resultado. C) Hacer un backup del servidor completo. D) Llamar a Oracle para pedir permiso.
Pregunta 5. ¿Cuál es la forma más segura de borrar TODAS las filas de una tabla?
A) `DELETE FROM tabla;` B) `TRUNCATE TABLE tabla;` C) `DROP TABLE tabla;` D) `DELETE FROM tabla;`
Pregunta 6. ¿Qué es INSERT ... SELECT?
A) Insertar un valor calculado. B) Insertar filas tomadas de un SELECT. C) Seleccionar filas para insertar después. D) Insertar con valores NULL.
Pregunta 7. ¿Por qué es peligroso `DROP DATABASE`?
A) No es peligroso, es una operación normal. B) Borra TODA la base de datos, no solo una tabla. Sin WHERE no hay filtro. C) Solo funciona en MySQL. D) Requiere permisos especiales.
Pregunta 8. Si ejecutas `DELETE FROM pedidos WHERE cliente_id = 99;` y el cliente 99 no existe, ¿qué pasa?
A) La query falla con error. B) Se borra la base de datos. C) La query se ejecuta sin error, pero no se borra nada (0 filas afectadas). D) Se borra el primer pedido de la tabla.
Pregunta 9. ¿Qué hace `INSERT INTO clientes (nombre) VALUES ('Juan');` si la columna email es NOT NULL?
A) La query falla porque falta email. B) Se inserta con email = NULL. C) Se inserta con email = '' (cadena vacía). D) Se inserta con email = 0.
Pregunta 10. En el patrón seguro "SELECT, verificar, UPDATE", ¿cuál es el paso más importante?
A) Hacer backup antes del UPDATE. B) Verificar que el SELECT devuelve exactamente las filas que quieres modificar. C) Tener transacciones activas. D) Usar LIMIT en el UPDATE.
📝 Quest 8 — Preguntas abiertas
Pregunta 11. Explica con tus palabras la diferencia entre DELETE, TRUNCATE y DROP. Da un ejemplo de cuándo usarías cada uno.
Pregunta 12. ¿Por qué es buena práctica envolver operaciones UPDATE/DELETE múltiples en una transacción? ¿Cómo lo harías en MySQL? ¿Y en PostgreSQL?
Pregunta 13. Un compañero tuyo te dice: "No necesito probar con SELECT antes, ya sé lo que voy a modificar". Dale 2 razones por las que está equivocado, usando ejemplos concretos.
✅ Respuestas modelo — Quest 8
Pregunta 1: B. Pregunta 2: C (todas las filas se actualizan). Pregunta 3: A. Pregunta 4: B. Pregunta 5: B (TRUNCATE es el más eficiente y seguro, porque DROP borra la tabla completa). Pregunta 6: B. Pregunta 7: B (borra toda la BD). Pregunta 8: C (0 filas afectadas, sin error). Pregunta 9: A (falla por la constraint NOT NULL). Pregunta 10: B.
🏛️ Tras las huellas — Por Citlalli
"El tlacuilo y la responsabilidad de modificar"
En el calmécac mexica, modificar un registro tributario era un acto de alta responsabilidad. El tlacuilo debía:
1. Verificar antes de actuar: ver qué registros iba a afectar su cambio.
2. Documentar el cambio: el Códice Florentino y otros registros muestran que los tlacuilos anotaban al margen: "se modificó este registro porque el altépetl argumentó que su cosecha se perdió". El cambio tenía JUSTIFICACIÓN.
3. Dejar rastro de auditoría: si algo salía mal después, se podía rastrear quién hizo el cambio y por qué.
En bases de datos modernas, esto se traduce en:
1. `SELECT` antes de `UPDATE`/`DELETE`: verificar qué vas a afectar.
2. Comentarios en el código o tickets: documentar por qué se hizo el cambio. Esto es el equivalente del comentario marginal del tlacuilo.
3. Logs de auditoría: la base de datos guarda QUIÉN hizo el cambio y CUÁNDO. Eso es el equivalente del rastro del tlacuilo.
Tres lecciones de los tlacuilos para tu trabajo:
1. La modificación no es borrar y reescribir; es CAMBIAR con razón. Si modificas un precio, registra por qué.
2. La prueba antes de la acción es una práctica milenaria. No es paranoia moderna; es sabiduría acumulada.
3. El DBA es el guardián de los datos, no su dueño. Como el tlacuilo, tu trabajo es cuidarlos para las siguientes generaciones.
En tu cuaderno, anota: ¿qué log de auditoría usa tu base de datos actual? Si no usas ninguno, es una mejora que puedes proponer a tu equipo.
📓 Cierre del cuaderno — 4 líneas para escribir a mano
1. La regla que más me impactó fue:>
2. El error que más miedo me dio fue:>
3. La sensación después del simulacro de desastre fue:>
4. Un compromiso conmigo mismo sobre cómo voy a usar estas reglas:
🚀 ¿Qué sigue?
En el Tema 9 — JOIN: unir tablas como un detective une pistas vamos a ver la operación más poderosa de SQL: combinar datos de múltiples tablas. Por ahora solo hemos trabajado con una tabla a la vez; con JOIN vamos a sacar el verdadero poder de las bases de datos relacionales.