Módulo 5: Bases de Datos Relacionales

Relaciones en SQL

Lección 25 de 33 del Curso Roadmap Learning Laravel

Duración: 1 hora
Nivel: Principiante (requiere conocimientos de HTML, CSS, JavaScript, PHP básico, MySQL, y SQL básico: CREATE, INSERT, SELECT, UPDATE, DELETE)
Objetivo: Comprender cómo usar JOINs (INNER, LEFT) para consultar datos relacionados en bases de datos relacionales, y aplicar relaciones uno a muchos y muchos a muchos, como preparación para gestionar datos complejos en aplicaciones web.
Materiales necesarios:

  • Computadora con:
    • XAMPP, WAMP, o MAMP (incluye MySQL/MariaDB, descarga gratuita desde sus sitios oficiales).
    • phpMyAdmin (incluido en XAMPP) o un cliente MySQL como MySQL Workbench (descarga gratuita desde mysql.com).
    • Editor de texto (recomendado: VS Code, descarga gratuita desde code.visualstudio.com).
  • Navegador web (Chrome, Firefox, etc.).
  • Alternativa: Entorno online con soporte MySQL (por ejemplo, Repl.it, limitado).
    Contexto: Las relaciones en SQL, implementadas con JOINs, permiten combinar datos de múltiples tablas, como usuarios y sus publicaciones, o productos y categorías. En Laravel, Eloquent simplifica estas consultas, pero entender JOINs es fundamental para consultas personalizadas.

Introducción a relaciones y JOINs (15 minutos)

Explicación:
En bases de datos relacionales, las tablas se conectan mediante claves primarias y claves foráneas (vistos en Lección 1 del Módulo 5). Los JOINs permiten consultar datos de varias tablas basándose en estas relaciones.

Conceptos clave:

  • Relaciones:
    • Uno a muchos (1:N): Un registro en una tabla se relaciona con varios en otra.
      • Ejemplo: Un usuario tiene muchos posts (usuarios.id → posts.id_usuario).
    • Muchos a muchos (N:N): Múltiples registros en una tabla se relacionan con múltiples registros en otra, usando una tabla intermedia.
      • Ejemplo: Estudiantes y cursos, con una tabla estudiantes_cursos.
  • JOINs: Operaciones SQL para combinar tablas. Tipos principales:
    • INNER JOIN: Devuelve solo los registros que coinciden en ambas tablas.
      • Ejemplo: Usuarios con posts (excluye usuarios sin posts).
    • LEFT JOIN: Devuelve todos los registros de la tabla izquierda y los coincidentes de la derecha (si no hay coincidencia, devuelve NULL).
      • Ejemplo: Todos los usuarios, con o sin posts.
  • Sintaxis básica:
    SELECT columnas
    FROM tabla1
    [INNER|LEFT] JOIN tabla2 ON tabla1.columna = tabla2.columna;

Por qué es importante:

  • Los JOINs permiten consultas complejas, como mostrar productos con sus categorías o usuarios con sus publicaciones.
  • En Laravel, Eloquent usa relaciones (hasMany, belongsTo), pero JOINs son esenciales para consultas avanzadas o personalizadas.

Punto clave: Los JOINs conectan tablas para obtener datos relacionados, una habilidad clave en bases de datos relacionales.

Actividad rápida (3 minutos):
Escribe en papel una relación 1:N que hayas visto (por ejemplo, del Módulo 4 o Lección 1). Ejemplo:

  • Relación: Un estudiante (estudiantes) tiene muchos registros de asistencia (asistencias).
  • Clave foránea: id_estudiante en asistencias → id en estudiantes.

Tipos de JOINs y relaciones (20 minutos)

Explicación:
Exploremos los JOINs y cómo se aplican a relaciones 1:N y N:N.

INNER JOIN:

  • Devuelve registros que tienen coincidencias en ambas tablas.
  • Sintaxis:
    SELECT columnas
    FROM tabla1
    INNER JOIN tabla2 ON tabla1.columna = tabla2.columna;
  • Ejemplo (1:N): Usuarios y sus posts.
    SELECT usuarios.nombre, posts.titulo
    FROM usuarios
    INNER JOIN posts ON usuarios.id = posts.id_usuario;
    • Solo muestra usuarios que tienen posts.

LEFT JOIN:

  • Devuelve todos los registros de la tabla izquierda, con coincidencias de la derecha o NULL si no hay.
  • Sintaxis:
    SELECT columnas
    FROM tabla1
    LEFT JOIN tabla2 ON tabla1.columna = tabla2.columna;
  • Ejemplo (1:N): Todos los usuarios, con o sin posts.
    SELECT usuarios.nombre, posts.titulo
    FROM usuarios
    LEFT JOIN posts ON usuarios.id = posts.id_usuario;
    • Muestra todos los usuarios; si no tienen posts, titulo es NULL.

Relaciones uno a muchos (1:N):

  • Común en aplicaciones web.
  • Ejemplo: Una categoría tiene muchos productos.
    • Tablas: categorias (id, nombre), productos (id, nombre, id_categoria).
    • Consulta:
      SELECT categorias.nombre, productos.nombre
      FROM categorias
      LEFT JOIN productos ON categorias.id = productos.id_categoria;

Relaciones muchos a muchos (N:N):

  • Requiere una tabla intermedia.
  • Ejemplo: Estudiantes y cursos.
    • Tablas:
      • estudiantes (id, nombre).
      • cursos (id, nombre).
      • estudiantes_cursos (id_estudiante, id_curso).
    • Consulta:
      SELECT estudiantes.nombre, cursos.nombre
      FROM estudiantes
      INNER JOIN estudiantes_cursos ON estudiantes.id = estudiantes_cursos.id_estudiante
      INNER JOIN cursos ON estudiantes_cursos.id_curso = cursos.id;
    • Muestra estudiantes y los cursos en los que están inscritos.

Notas importantes:

  • INNER JOIN es más restrictivo; LEFT JOIN es más inclusivo.
  • Usa alias para simplificar: FROM usuarios AS u JOIN posts AS p ON u.id = p.id_usuario.
  • Prueba consultas en phpMyAdmin para ver cómo cambian los resultados entre INNER y LEFT.

Cómo probarlo:

  1. Crea una base de datos pruebas en phpMyAdmin.
  2. Crea tablas simples:
    CREATE TABLE usuarios (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nombre VARCHAR(100) NOT NULL
    );
    CREATE TABLE posts (
        id INT AUTO_INCREMENT PRIMARY KEY,
        titulo VARCHAR(200) NOT NULL,
        id_usuario INT,
        FOREIGN KEY (id_usuario) REFERENCES usuarios(id)
    );
    INSERT INTO usuarios (nombre) VALUES ('Ana'), ('Juan');
    INSERT INTO posts (titulo, id_usuario) VALUES ('Post 1', 1);
  3. Prueba:
    • INNER JOIN: SELECT usuarios.nombre, posts.titulo FROM usuarios INNER JOIN posts ON usuarios.id = posts.id_usuario;
      • Resultado: Solo “Ana” con “Post 1”.
    • LEFT JOIN: SELECT usuarios.nombre, posts.titulo FROM usuarios LEFT JOIN posts ON usuarios.id = posts.id_usuario;
      • Resultado: “Ana” con “Post 1”, “Juan” con NULL.

Punto clave: Los JOINs permiten combinar datos relacionados, esenciales para consultas en aplicaciones reales.

Actividad rápida (3 minutos):
Escribe en papel una consulta INNER JOIN para unir clientes y pedidos. Solución sugerida:

SELECT clientes.nombre, pedidos.id
FROM clientes
INNER JOIN pedidos ON clientes.id = pedidos.id_cliente;

3. Ejemplo práctico: Consulta que une usuarios con sus publicaciones (15 minutos)

Explicación:
Crearemos una base de datos con usuarios y publicaciones, y usaremos JOINs para consultarlas.

Paso 1: Crear las tablas:

  • En phpMyAdmin, crea la base de datos blog y ejecuta:
    CREATE TABLE usuarios (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nombre VARCHAR(100) NOT NULL,
        email VARCHAR(100) NOT NULL UNIQUE
    );
    
    CREATE TABLE posts (
        id INT AUTO_INCREMENT PRIMARY KEY,
        titulo VARCHAR(200) NOT NULL,
        contenido TEXT NOT NULL,
        id_usuario INT,
        FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE
    );

Paso 2: Insertar datos:

  • Ejecuta:
    INSERT INTO usuarios (nombre, email) VALUES 
        ('Ana', 'ana@correo.com'),
        ('Juan', 'juan@correo.com'),
        ('María', 'maria@correo.com');
    
    INSERT INTO posts (titulo, contenido, id_usuario) VALUES 
        ('Mi primer post', 'Contenido del post 1', 1),
        ('Otro post', 'Contenido del post 2', 1),
        ('Post de Juan', 'Contenido del post 3', 2);

Paso 3: Consultas con JOINs:

  • INNER JOIN: Usuarios con posts.
    SELECT usuarios.nombre, usuarios.email, posts.titulo
    FROM usuarios
    INNER JOIN posts ON usuarios.id = posts.id_usuario;
    • Resultado esperado:
      +--------+--------------------+------------------+
      | nombre | email              | titulo           |
      +--------+--------------------+------------------+
      | Ana    | ana@correo.com     | Mi primer post   |
      | Ana    | ana@correo.com     | Otro post        |
      | Juan   | juan@correo.com    | Post de Juan     |
      +--------+--------------------+------------------+
    • Nota: María no aparece (no tiene posts).
  • LEFT JOIN: Todos los usuarios, con o sin posts.
    SELECT usuarios.nombre, usuarios.email, posts.titulo
    FROM usuarios
    LEFT JOIN posts ON usuarios.id = posts.id_usuario;
    
    • Resultado esperado:
      +--------+--------------------+------------------+
      | nombre | email              | titulo           |
      +--------+--------------------+------------------+
      | Ana    | ana@correo.com     | Mi primer post   |
      | Ana    | ana@correo.com     | Otro post        |
      | Juan   | juan@correo.com    | Post de Juan     |
      | María  | maria@correo.com   | NULL             |
      +--------+--------------------+------------------+
    • Nota: María aparece con titulo = NULL.

Cómo funciona:

  • INNER JOIN: Solo muestra usuarios con al menos un post (relación 1:N).
  • LEFT JOIN: Incluye a todos los usuarios, útil para ver quién no ha publicado.
  • ON usuarios.id = posts.id_usuario: Vincula las tablas usando la clave foránea.

Punto clave: Este ejemplo muestra cómo los JOINs recuperan datos relacionados, una práctica común en aplicaciones web como blogs.

Actividad rápida (3 minutos):
Modifica la consulta LEFT JOIN (en papel) para incluir solo el id del post. Solución sugerida:

SELECT usuarios.nombre, usuarios.email, posts.id
FROM usuarios
LEFT JOIN posts ON usuarios.id = posts.id_usuario;

Resumen y preparación para la tarea (10 minutos)

Resumen:

  • Relaciones:
    • Uno a muchos (1:N): Una tabla conecta con varias (por ejemplo, usuarios y posts).
    • Muchos a muchos (N:N): Requiere tabla intermedia (por ejemplo, estudiantes y cursos).
  • JOINs:
    • INNER JOIN: Coincidencias en ambas tablas.
    • LEFT JOIN: Todos los registros de la tabla izquierda.
  • Ejemplo: Consultamos usuarios y sus posts con INNER y LEFT JOIN.
  • Los JOINs son esenciales para combinar datos en MySQL, como en el proyecto del Módulo 4.

Preparación para la tarea:
La tarea pide crear una consulta que relacione productos y categorías.

  • Estrategia:
    • Usa las tablas productos y categorías (similares a las de Lección 1, Módulo 5).
    • Aplica INNER JOIN o LEFT JOIN para mostrar productos con sus categorías.
    • Inserta datos de prueba para verificar los resultados.
  • Lógica básica:
    SELECT productos.nombre, categorias.nombre
    FROM productos
    INNER JOIN categorias ON productos.id_categoria = categorias.id;

Punto clave: Practicar JOINs refuerza la capacidad de consultar datos relacionados, una habilidad clave para aplicaciones web.


Tarea práctica: Crea una consulta que relacione productos y categorías

Instrucciones:

  1. Usa las siguientes tablas (basadas en Lección 1, Módulo 5):
    CREATE TABLE categorias (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nombre VARCHAR(50) NOT NULL
    );
    
    CREATE TABLE productos (
        id INT AUTO_INCREMENT PRIMARY KEY,
        nombre VARCHAR(100) NOT NULL,
        precio DECIMAL(10,2) NOT NULL,
        id_categoria INT,
        FOREIGN KEY (id_categoria) REFERENCES categorias(id) ON DELETE SET NULL
    );
  2. Inserta datos de prueba:
    INSERT INTO categorias (nombre) VALUES ('Electrónica'), ('Ropa'), ('Hogar');
    INSERT INTO productos (nombre, precio, id_categoria) VALUES 
        ('Teléfono', 499.99, 1),
        ('Laptop', 999.99, 1),
        ('Camiseta', 29.99, 2),
        ('Sofá', 399.99, NULL);
  3. Escribe 2 consultas SQL con JOINs:
    • Consulta 1: Usa INNER JOIN para listar productos y sus categorías (solo productos con categoría asignada).
    • Consulta 2: Usa LEFT JOIN para listar todos los productos, con o sin categoría.
  4. Entregable:
    • Un archivo de texto o documento con:
      • Las 2 consultas SQL.
      • Los resultados esperados (descritos o capturas de phpMyAdmin).
    • Opcional: Capturas de pantalla de phpMyAdmin mostrando los resultados.
  5. Usa el siguiente ejemplo como guía:
    -- Consulta 1: INNER JOIN
    SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria
    FROM productos
    INNER JOIN categorias ON productos.id_categoria = categorias.id;
    
    -- Consulta 2: LEFT JOIN
    SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria
    FROM productos
    LEFT JOIN categorias ON productos.id_categoria = categorias.id;
  6. Pasos para completar:
    • Paso 1: Crea la base de datos tienda en phpMyAdmin.
    • Paso 2: Crea las tablas categorias y productos.
    • Paso 3: Inserta los datos de prueba.
    • Paso 4: Escribe las 2 consultas solicitadas.
    • Paso 5: Prueba las consultas en phpMyAdmin (pestaña “SQL”).
      • Verifica los resultados en la pestaña “Browse” o en la salida de la consulta.
    • Paso 6: Entrega las consultas y los resultados esperados.

Ejemplo de solución esperada:

  • Consultas:
    -- INNER JOIN
    SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria
    FROM productos
    INNER JOIN categorias ON productos.id_categoria = categorias.id;
    
    -- LEFT JOIN
    SELECT productos.nombre AS producto, productos.precio, categorias.nombre AS categoria
    FROM productos
    LEFT JOIN categorias ON productos.id_categoria = categorias.id;
  • Resultados esperados:
    • INNER JOIN:
      +------------+--------+-------------+
      | producto   | precio | categoria   |
      +------------+--------+-------------+
      | Teléfono   | 499.99 | Electrónica |
      | Laptop     | 999.99 | Electrónica |
      | Camiseta   |  29.99 | Ropa        |
      +------------+--------+-------------+
    • LEFT JOIN:
      +------------+--------+-------------+
      | producto   | precio | categoria   |
      +------------+--------+-------------+
      | Teléfono   | 499.99 | Electrónica |
      | Laptop     | 999.99 | Electrónica |
      | Camiseta   |  29.99 | Ropa        |
      | Sofá       | 399.99 | NULL        |
      +------------+--------+-------------+

Tiempo estimado: 30-45 minutos (puedes hacerlo después de la lección).
Entregable:

  • Archivo de texto con las 2 consultas SQL y los resultados esperados.
  • Opcional: Capturas de phpMyAdmin con los resultados.

Consejo:

  • Usa alias (AS producto, AS categoria) para clarificar los nombres de las columnas.
  • Prueba primero el INNER JOIN, luego el LEFT JOIN, y compara los resultados.
  • Verifica los datos insertados con SELECT * FROM productos; y SELECT * FROM categorias; antes de ejecutar los JOINs.

© Copyright Cursos Laravel :: 2025 Términos y condiciones