Curso de MySQL
Insertar registros en MySQL: INSERT INTO con ejemplos
Por Víctor Peña · Publicado el

Hola, ¿cómo están? Continuando con el curso de MySQL, hoy empezamos a llenar de datos las tablas que creamos. Con la estructura y las relaciones listas, toca el INSERT.
¡Empecemos!
La sentencia básica
INSERT INTO especialidades (nombre, descripcion)
VALUES ('Cardiología', 'Especialidad del corazón y sistema circulatorio');
Se indican las columnas entre paréntesis y los valores en el mismo orden.
Fíjate en que no incluimos el id: al ser AUTO_INCREMENT, MySQL lo asigna solo.
Especificar siempre las columnas
Existe una forma abreviada que omite los nombres:
INSERT INTO especialidades VALUES (NULL, 'Pediatría', 'Atención a niños');
Evítala. Depende del orden exacto de las columnas, así que el día que alguien agregue una columna nueva con ALTER TABLE, todas tus sentencias dejan de funcionar o, peor, guardan los datos en la columna equivocada.
Escribir los nombres cuesta unos segundos y hace la sentencia legible y estable.
Insertar varios registros a la vez
INSERT INTO especialidades (nombre, descripcion) VALUES
('Cardiología', 'Corazón y sistema circulatorio'),
('Pediatría', 'Atención médica a niños'),
('Traumatología', 'Huesos, músculos y articulaciones'),
('Dermatología', 'Enfermedades de la piel');
Esto no es solo comodidad de escritura: es mucho más rápido que cuatro sentencias separadas, porque hay una sola comunicación con el servidor y una sola escritura al disco.
Con volúmenes grandes la diferencia es enorme. Insertar mil filas de una en una puede tardar segundos; en lotes de cien, milisegundos.
Valores por defecto y NULL
INSERT INTO pacientes (cedula, nombre, apellido, fecha_nacimiento, telefono)
VALUES ('1234567', 'Ana', 'Torres', '1990-06-15', NULL);
Las columnas que no menciones toman su valor por defecto, o NULL si lo admiten. Como creado_en tiene DEFAULT CURRENT_TIMESTAMP, se llena sola.
Ojo con la diferencia entre estos tres:
telefono = NULL -- desconocido, no tenemos el dato
telefono = '' -- cadena vacía, sí es un dato: uno vacío
telefono = '0' -- un valor concreto
NULL significa «no se sabe», y se comporta distinto en las comparaciones. Lo veremos al llegar a las consultas.
Formato de fechas
Siempre AAAA-MM-DD, aunque después lo muestres de otra forma:
INSERT INTO citas (paciente_id, doctor_id, fecha, hora, costo)
VALUES (1, 1, '2026-04-20', '09:30:00', 250.00);
Y para la fecha actual:
INSERT INTO citas (paciente_id, doctor_id, fecha, hora)
VALUES (1, 1, CURDATE(), CURTIME());
CURDATE()— la fecha de hoyCURTIME()— la hora actualNOW()— fecha y hora juntas
Obtener el id generado
Después de insertar, muchas veces necesitas el id del registro nuevo para insertar los relacionados:
INSERT INTO pacientes (cedula, nombre, apellido, fecha_nacimiento)
VALUES ('7654321', 'Luis', 'Gomez', '1985-03-22');
SELECT LAST_INSERT_ID();
Desde PHP, con PDO, es lastInsertId(), como vimos en el curso de PHP.
Un detalle importante: LAST_INSERT_ID() es por conexión. No devuelve el último id de la tabla, sino el último que tu conexión generó. Por eso funciona bien aunque haya cien usuarios insertando a la vez.
Insertar respetando las relaciones
Con claves foráneas declaradas, el orden importa:
-- 1. Primero la especialidad
INSERT INTO especialidades (nombre) VALUES ('Cardiología');
-- 2. Después el doctor, que la referencia
INSERT INTO doctores (matricula, nombre, apellido, especialidad_id)
VALUES ('MED-001', 'Carlos', 'Mendoza', 1);
-- 3. Y por último la cita
INSERT INTO citas (paciente_id, doctor_id, fecha, hora, costo)
VALUES (1, 1, '2026-04-20', '09:30:00', 250.00);
Si intentas insertar una cita con un doctor_id que no existe, MySQL la rechaza. Eso es la integridad referencial trabajando a tu favor.
INSERT IGNORE
Ignora los errores de duplicado en lugar de detenerse:
INSERT IGNORE INTO especialidades (nombre) VALUES ('Cardiología');
Si ya existe una especialidad con ese nombre —recuerda que la columna es UNIQUE—, la sentencia no hace nada y no falla.
Úsalo con cuidado: IGNORE silencia también otros errores, no solo los duplicados. Un dato demasiado largo se trunca sin avisar. Reserva su uso para cargas masivas donde ya sabes que puede haber repetidos.
ON DUPLICATE KEY UPDATE
Más preciso que IGNORE: inserta, y si el registro ya existe, lo actualiza.
INSERT INTO especialidades (nombre, descripcion)
VALUES ('Cardiología', 'Descripción actualizada')
ON DUPLICATE KEY UPDATE
descripcion = VALUES(descripcion);
Es lo que se conoce como upsert, y resulta muy útil al sincronizar datos desde un archivo o una API externa: no necesitas comprobar antes si el registro existe.
INSERT desde un SELECT
Puedes insertar el resultado de una consulta:
CREATE TABLE citas_archivo LIKE citas;
INSERT INTO citas_archivo
SELECT * FROM citas WHERE fecha < '2025-01-01';
Es la forma de archivar datos antiguos, mover información entre tablas o poblar una tabla de resumen.
Cargar datos desde un archivo
Para volúmenes grandes, la opción más rápida:
LOAD DATA INFILE '/ruta/pacientes.csv'
INTO TABLE pacientes
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(cedula, nombre, apellido, fecha_nacimiento, telefono);
IGNORE 1 ROWS salta la fila de encabezados del CSV.
Es órdenes de magnitud más rápido que insertar fila por fila. Si el servidor lo tiene restringido por seguridad, la alternativa desde phpMyAdmin es la pestaña Importar.
Datos de prueba para el curso
Ejecuta esto, porque lo vamos a usar en las próximas lecciones:
INSERT INTO especialidades (nombre, descripcion) VALUES
('Cardiología', 'Corazón y sistema circulatorio'),
('Pediatría', 'Atención médica a niños'),
('Traumatología', 'Huesos y articulaciones');
INSERT INTO doctores (matricula, nombre, apellido, telefono, especialidad_id) VALUES
('MED-001', 'Carlos', 'Mendoza', '70011122', 1),
('MED-002', 'Laura', 'Vargas', '70011133', 2),
('MED-003', 'Jorge', 'Rojas', '70011144', 3),
('MED-004', 'Elena', 'Quiroga', '70011155', 2);
INSERT INTO pacientes (cedula, nombre, apellido, fecha_nacimiento, telefono) VALUES
('1234567', 'Ana', 'Torres', '1990-06-15', '76980507'),
('2345678', 'Luis', 'Gomez', '1985-03-22', '76980508'),
('3456789', 'Marta', 'Silva', '2015-11-08', '76980509'),
('4567890', 'Pedro', 'Nina', '1978-01-30', NULL);
INSERT INTO citas (paciente_id, doctor_id, fecha, hora, costo, estado) VALUES
(1, 1, '2026-04-10', '09:00:00', 250.00, 'atendida'),
(1, 1, '2026-04-20', '09:30:00', 250.00, 'programada'),
(2, 3, '2026-04-11', '10:00:00', 300.00, 'atendida'),
(3, 2, '2026-04-12', '11:00:00', 200.00, 'atendida'),
(3, 4, '2026-04-25', '15:00:00', 200.00, 'programada'),
(4, 1, '2026-04-15', '16:30:00', 250.00, 'cancelada');
Errores comunes
- Omitir los nombres de las columnas.
- Insertar en el orden equivocado y violar una clave foránea.
- Fechas en formato local, como
20/04/2026. - Insertar mil filas una por una en lugar de por lotes.
- Usar
INSERT IGNOREsin entender que silencia otros errores. - Concatenar datos del usuario en la sentencia. Recuerda las consultas preparadas: es la puerta a la inyección SQL.
Para cerrar
INSERT es la sentencia más simple de las tres de manipulación, pero tiene detalles que marcan diferencia: especificar siempre las columnas, insertar por lotes cuando sean muchas filas, y conocer ON DUPLICATE KEY UPDATE para sincronizaciones.
En la siguiente lección veremos UPDATE y DELETE, donde un descuido cuesta bastante más caro.
Saludos y éxitos.
Norvic Software
Desarrollamos el software que tu empresa necesita
Somos una fábrica de software en Bolivia. Construimos sistemas a medida y aplicaciones móviles, y llevamos Inteligencia Artificial a las empresas que ya tienen un sistema funcionando.
- Chatbots con Inteligencia Artificial
- Creación de agentes de IA
- Integración de IA en tus sistemas
- Desarrollo de software a medida
- Aplicaciones móviles iOS y Android
- Consultoría y asesoramiento técnico
Cotización sin costo · Respuesta directa por WhatsApp