Curso de MySQL

Insertar registros en MySQL: INSERT INTO con ejemplos

Por Víctor Peña · Publicado el

Insertar registros en MySQL

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 hoy
  • CURTIME() — la hora actual
  • NOW() — 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 IGNORE sin 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.

Solicitar cotizaciónVer todos los servicios

Cotización sin costo · Respuesta directa por WhatsApp