Ruta 1

DBeaver + MySQL local (sin cPanel)

Objetivo: instalar MySQL en tu computadora, conectarte con DBeaver, crear una base de datos y practicar consultas (incluyendo JOIN).

1) ¿Qué es DBeaver y por qué lo usamos?

DBeaver es un cliente / gestor de bases de datos. No es una base de datos. DBeaver sirve para conectarse a un motor (en este curso: MySQL/MariaDB), escribir SQL, ejecutar scripts y ver resultados.

Idea clave:
• MySQL/MariaDB = el servidor de base de datos (donde viven las tablas).
• DBeaver = la herramienta para conectarte y trabajar con ese servidor.

2) Descarga

Recomendación para el curso: MySQL en puerto 3306 y un usuario (por ejemplo root) con contraseña.

3) Instalación (MySQL local)

Durante la instalación, cuida estos puntos:

Nota: Si ya tienes otro MySQL en tu equipo, podría ocupar el puerto 3306. En ese caso, se elige otro puerto (por ejemplo 3307).

4) Configuración de DBeaver (crear conexión)

Pasos para conectarte a MySQL local:

  1. Abre DBeaver.
  2. Menú: DatabaseNew Database Connection.
  3. Elige MySQL.
  4. Llena la conexión:

Finalmente:

5) Crear una base de datos (SQL)

Una base de datos (database) es un contenedor de tablas. En local puedes crear una de práctica para el curso.

CREATE DATABASE IF NOT EXISTS curso_practica
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

USE curso_practica;

Explicación línea por línea

6) Crear 4 tablas (usuarios, clientes, productos, ventas)

Estas tablas permiten practicar CRUD y JOIN. Las relaciones principales serán:

USE curso_practica;

DROP TABLE IF EXISTS ventas;
DROP TABLE IF EXISTS productos;
DROP TABLE IF EXISTS clientes;
DROP TABLE IF EXISTS usuarios;

CREATE TABLE usuarios (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  correo VARCHAR(150) NOT NULL UNIQUE,
  rol VARCHAR(30) NOT NULL DEFAULT 'alumno',
  activo TINYINT(1) NOT NULL DEFAULT 1,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE clientes (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  telefono VARCHAR(20) NULL,
  email VARCHAR(150) NULL,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE productos (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(120) NOT NULL,
  precio DECIMAL(10,2) NOT NULL,
  stock INT UNSIGNED NOT NULL DEFAULT 0,
  activo TINYINT(1) NOT NULL DEFAULT 1,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE ventas (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  usuario_id INT UNSIGNED NOT NULL,
  cliente_id INT UNSIGNED NOT NULL,
  producto_id INT UNSIGNED NOT NULL,
  cantidad INT UNSIGNED NOT NULL DEFAULT 1,
  total DECIMAL(10,2) NOT NULL,
  fecha DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,

  CONSTRAINT fk_ventas_usuario
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id)
    ON UPDATE CASCADE ON DELETE RESTRICT,

  CONSTRAINT fk_ventas_cliente
    FOREIGN KEY (cliente_id) REFERENCES clientes(id)
    ON UPDATE CASCADE ON DELETE RESTRICT,

  CONSTRAINT fk_ventas_producto
    FOREIGN KEY (producto_id) REFERENCES productos(id)
    ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB;

Explicación de lo más importante

Sugerencia práctica: en DBeaver, pega el script completo y ejecútalo para crear toda la base de un solo paso.

7) Datos de prueba (opcional)

Para poder practicar JOIN, primero necesitamos registros en las tablas:

USE curso_practica;

INSERT INTO usuarios (nombre, correo, rol, activo) VALUES
('Ana López', 'ana.lopez@mail.com', 'alumno', 1),
('Luis García', 'luis.garcia@mail.com', 'alumno', 1),
('María Pérez', 'maria.perez@mail.com', 'alumno', 1);

INSERT INTO clientes (nombre, telefono, email) VALUES
('Cliente Uno', '4771112233', 'cliente1@mail.com'),
('Cliente Dos', '4772223344', 'cliente2@mail.com');

INSERT INTO productos (nombre, precio, stock, activo) VALUES
('Teclado', 399.00, 10, 1),
('Mouse', 199.00, 20, 1),
('Monitor 24"', 2799.00, 5, 1);

-- total = precio * cantidad (aquí lo dejamos calculado manualmente)
INSERT INTO ventas (usuario_id, cliente_id, producto_id, cantidad, total) VALUES
(1, 1, 1, 1, 399.00),
(2, 1, 2, 2, 398.00),
(3, 2, 3, 1, 2799.00);

8) Prompt para ChatGPT (generar un esquema de BD)

Cuando ya entiendas cada línea de CREATE TABLE, puedes usar un prompt para pedir un esquema completo para tu proyecto. Este prompt se debe ajustar a lo que tu sistema necesite.

Actúa como arquitecto de base de datos MySQL.

Necesito un esquema para una base de datos llamada: curso_practica

Requisitos:
- Tablas: usuarios, clientes, productos, ventas
- Primary keys autoincrement (id)
- Relaciones con foreign keys:
  ventas.usuario_id -> usuarios.id
  ventas.cliente_id -> clientes.id
  ventas.producto_id -> productos.id
- Tipos de dato adecuados (VARCHAR, INT, DECIMAL, DATETIME)
- Incluir ENGINE=InnoDB y charset utf8mb4
- Agregar restricciones básicas: NOT NULL, DEFAULT, UNIQUE donde aplique
- Incluir DROP TABLE IF EXISTS en el orden correcto para re-ejecutar el script

Entrega:
1) Script SQL completo (CREATE DATABASE, USE, CREATE TABLE)
2) Explicación breve de decisiones (por qué ese tipo de dato y esas llaves)

9) Consultas de práctica (ejemplos)

Ejemplos para practicar lectura y filtros:

-- 1) Ver todos los usuarios
SELECT * FROM usuarios;

-- 2) Usuarios activos ordenados por nombre
SELECT id, nombre, correo
FROM usuarios
WHERE activo = 1
ORDER BY nombre ASC;

-- 3) Productos con stock mayor a 0
SELECT id, nombre, precio, stock
FROM productos
WHERE stock > 0
ORDER BY stock DESC;

-- 4) Ventas por fecha (más recientes primero)
SELECT id, usuario_id, cliente_id, producto_id, total, fecha
FROM ventas
ORDER BY fecha DESC;

10) JOIN: qué es, para qué sirve y cómo se usa

Un JOIN se usa para combinar datos de dos (o más) tablas relacionadas. La base de la relación es que una tabla tiene una foreign key que apunta a la primary key de otra tabla.

Ejemplo de relación:
En ventas guardamos usuario_id, pero el nombre del usuario está en usuarios.
Con JOIN podemos obtener: venta + nombre del usuario en una misma consulta.

INNER JOIN

Devuelve solo registros que tienen coincidencia en ambas tablas (solo la intersección).

Diagrama INNER JOIN

Imagen de referencia: assets/img/inner_join.png

-- Ventas + nombre del usuario (solo si existe el usuario)
SELECT v.id, v.total, v.fecha, u.nombre AS usuario
FROM ventas v
INNER JOIN usuarios u ON u.id = v.usuario_id
ORDER BY v.fecha DESC;

LEFT JOIN

Devuelve todos los registros de la tabla izquierda, aunque no haya coincidencia en la derecha. Cuando no haya coincidencia, los campos de la derecha aparecen como NULL.

Diagrama LEFT JOIN

Imagen de referencia: assets/img/left_join.png

-- Lista todos los clientes aunque no tengan ventas
SELECT c.id, c.nombre AS cliente, v.id AS venta_id, v.total
FROM clientes c
LEFT JOIN ventas v ON v.cliente_id = c.id
ORDER BY c.nombre ASC;

RIGHT JOIN

Devuelve todos los registros de la tabla derecha, aunque no haya coincidencia en la izquierda. En la práctica web se usa más LEFT JOIN (porque controlas el lado izquierdo).

Diagrama RIGHT JOIN

Imagen de referencia: assets/img/right_join.png

-- Lista todas las ventas aunque el cliente no exista (si hubiera registros inconsistentes)
SELECT v.id, v.total, c.nombre AS cliente
FROM clientes c
RIGHT JOIN ventas v ON v.cliente_id = c.id
ORDER BY v.id DESC;

JOIN con productos

-- Ventas + nombre del producto
SELECT v.id, v.cantidad, v.total, p.nombre AS producto
FROM ventas v
INNER JOIN productos p ON p.id = v.producto_id
ORDER BY v.id DESC;

JOIN combinando varias tablas

-- Venta + usuario + cliente + producto
SELECT
  v.id,
  v.fecha,
  u.nombre AS usuario,
  c.nombre AS cliente,
  p.nombre AS producto,
  v.cantidad,
  v.total
FROM ventas v
INNER JOIN usuarios u  ON u.id = v.usuario_id
INNER JOIN clientes c ON c.id = v.cliente_id
INNER JOIN productos p ON p.id = v.producto_id
ORDER BY v.fecha DESC;

11) Ejercicios para el pizarrón (5)

Escribe la consulta SQL. No se incluyen respuestas en esta sección.

  1. Obtener id, nombre y correo de usuarios activos, ordenados por nombre A→Z.
  2. Obtener los productos con stock > 0, mostrando nombre, precio y stock, ordenados por stock de mayor a menor.
  3. Obtener todas las ventas mostrando: id de venta, total, fecha y el nombre del usuario (JOIN).
  4. Obtener todas las ventas mostrando: id, cantidad, total y el nombre del producto (JOIN).
  5. Listar todos los clientes aunque no tengan ventas, mostrando: nombre del cliente, id de venta (si existe) y total (LEFT JOIN).