Antes de escribir una sola línea de SQL, antes de crear una sola tabla, los buenos diseñadores de bases de datos hacen algo que parece anticuado pero que lo cambia todo: dibujan un diagrama.
Ese diagrama se llama Modelo Entidad-Relación. Y es la diferencia entre una base de datos bien pensada desde el principio y una llena de parches, redundancias y problemas que aparecen cuando ya es tarde para rediseñarla.
En este artículo vas a aprender qué es el Modelo ER, cómo leer y construir un diagrama desde cero, qué significan todos sus símbolos y cómo transformarlo en tablas SQL reales. Con el mismo ejemplo evolucionando de principio a fin.
¿Qué es el Modelo Entidad-Relación?
El Modelo Entidad-Relación (también llamado Modelo ER o ERD por sus siglas en inglés: Entity-Relationship Diagram) es una herramienta de diseño conceptual que representa de forma visual cómo se organizan los datos de un sistema y cómo se relacionan entre sí.
Fue propuesto por el informático Peter Chen en 1976 en un paper que se convirtió en uno de los más citados de la historia de la informática. Casi 50 años después, sigue siendo el estándar para el diseño de bases de datos relacionales.
La clave del Modelo ER es que es independiente de la tecnología. No importa si luego vas a usar MySQL, PostgreSQL, Oracle o SQL Server. El diagrama representa la realidad del sistema de información, no la implementación técnica concreta.
¿Para qué sirve exactamente?
- 🗺️ Planificar antes de construir — detectar problemas de diseño antes de escribir SQL
- 💬 Comunicar — es un lenguaje visual que entienden tanto programadores como clientes sin conocimientos técnicos
- 📐 Documentar — sirve como documentación viva de cómo está estructurada la base de datos
- 🔍 Analizar — identificar qué datos necesita el sistema y cómo se relacionan
Los 4 componentes fundamentales del Modelo ER
Un diagrama ER se construye con cuatro elementos básicos. Una vez que los conoces, puedes leer cualquier diagrama ER del mundo.
🟦 1. Entidad — las "cosas" del sistema
Una entidad representa un objeto, persona o concepto del mundo real sobre el que queremos guardar información. Se representa con un rectángulo.
Pregunta clave: ¿De qué "cosas" necesito guardar datos?
Ejemplos de entidades:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ CLIENTE │ │ PRODUCTO │ │ PEDIDO │ │EMPLEADO │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
Regla práctica: si necesitas guardar más de un dato sobre algo,
probablemente sea una entidad.Entidades fuertes vs débiles
ENTIDAD FUERTE — existe por sí sola, tiene identidad propia
┌──────────┐
│ CLIENTE │ ← existe aunque no tenga pedidos
└──────────┘
ENTIDAD DÉBIL — depende de otra entidad para existir
╔══════════╗
║ DETALLE ║ ← un detalle de pedido no existe sin el pedido
╚══════════╝ (se representa con doble rectángulo)🔵 2. Atributo — las propiedades de las entidades
Un atributo es una característica o propiedad de una entidad. Se representa con un óvalo o elipse conectado a la entidad.
┌────────────────────────────────────────┐
│ │
(id_cliente) (nombre) (email) (telefono)
│ │ │ │
┌──────────────────────────────────────┐
│ CLIENTE │
└──────────────────────────────────────┘
Tipos de atributos:
(atributo) → atributo simple
(atributo_clave) → atributo identificador (se subraya)
((multivaluado)) → puede tener varios valores (doble óvalo)
(derivado)... → se calcula de otros atributos (óvalo punteado)
Ejemplo:
id_cliente → atributo clave (subrayado), identifica unívocamente
nombre → atributo simple
telefono → multivaluado (una persona puede tener varios teléfonos)
edad → derivado (se calcula desde fecha_nacimiento)◆ 3. Relación — cómo se conectan las entidades
Una relación describe cómo dos entidades están conectadas entre sí. Se representa con un rombo etiquetado con un verbo.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ CLIENTE │ ────────◆ REALIZA ◆──────────── │ PEDIDO │
└──────────┘ └──────────┘ └──────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐
│ PEDIDO │ ────────◆ CONTIENE◆──────────── │PRODUCTO │
└──────────┘ └──────────┘ └──────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐
│EMPLEADO │ ────────◆PERTENECE◆──────────── │ DEPTO │
└──────────┘ └──────────┘ └──────────┘
La relación se etiqueta siempre con un VERBO
que describe cómo se asocian las entidades.🔢 4. Cardinalidad — cuántos de cada lado
La cardinalidad define cuántas instancias de una entidad pueden relacionarse con cuántas instancias de la otra. Es el concepto más importante del Modelo ER y el que más confunde a los principiantes.
Hay tres tipos básicos de cardinalidad:
1:1 — Uno a Uno
1:N — Uno a Muchos (o Muchos a Uno)
N:M — Muchos a MuchosLos tipos de cardinalidad — con ejemplos del mundo real
1:1 — Uno a Uno
Una instancia de la entidad A se relaciona con exactamente una instancia de la entidad B, y viceversa.
┌──────────┐ 1 1 ┌──────────────┐
│ PERSONA │────────────│ PASAPORTE │
└──────────┘ └──────────────┘
Cada persona tiene un único pasaporte.
Cada pasaporte pertenece a una única persona.
Más ejemplos 1:1:
PAÍS ──────── CAPITAL (un país tiene una capital)
COCHE ─────── MATRÍCULA (un coche tiene una matrícula)
EMPLEADO ──── ESCRITORIO (en oficina asignada)Las relaciones 1:1 son las menos comunes. A menudo se puede fusionar la información en una sola tabla.
1:N — Uno a Muchos
Una instancia de A puede relacionarse con muchas instancias de B, pero cada instancia de B se relaciona con solo una de A.
┌──────────┐ 1 N ┌──────────┐
│ CLIENTE │────────────│ PEDIDO │
└──────────┘ └──────────┘
Un cliente puede hacer muchos pedidos.
Cada pedido pertenece a un solo cliente.
Más ejemplos 1:N:
DEPARTAMENTO ──────── EMPLEADOS (un depto tiene muchos empleados)
AUTOR ─────────────── LIBROS (un autor escribe muchos libros)
CATEGORÍA ─────────── PRODUCTOS (una categoría tiene muchos productos)
PAÍS ──────────────── CIUDADES (un país tiene muchas ciudades)Las relaciones 1:N son las más frecuentes en el diseño de bases de datos. Se implementan poniendo la clave primaria del lado "1" como clave foránea en el lado "N".
N:M — Muchos a Muchos
Muchas instancias de A pueden relacionarse con muchas instancias de B, y viceversa.
┌──────────┐ N M ┌──────────┐
│ESTUDIANTE│────────────│ CURSO │
└──────────┘ └──────────┘
Un estudiante puede inscribirse en muchos cursos.
Un curso puede tener muchos estudiantes.
Más ejemplos N:M:
MÉDICO ──────────── PACIENTE (un médico atiende muchos pacientes)
ACTOR ───────────── PELÍCULA (un actor actúa en muchas películas)
PRODUCTO ────────── PEDIDO (un pedido puede tener muchos productos)
ETIQUETA ────────── ARTÍCULO (un artículo puede tener varias etiquetas)⚠️ Importante: Las relaciones N:M no se pueden implementar directamente en una base de datos relacional. Siempre se resuelven creando una tabla intermedia (tabla de asociación). Más sobre esto al final del artículo.
Participación: total vs parcial
Además de la cardinalidad, las relaciones tienen otra propiedad: la participación, que indica si la presencia en la relación es obligatoria o no.
PARTICIPACIÓN TOTAL (doble línea) — toda instancia DEBE participar
PARTICIPACIÓN PARCIAL (línea simple) — la participación es OPCIONAL
Ejemplo:
┌──────────┐══════◆ TRABAJA ◆─────── ┌──────────┐
│EMPLEADO │ EN │ PROYECTO │
└──────────┘ └──────────┘
Empleado === doble línea → todo empleado DEBE trabajar en al menos un proyecto
Proyecto --- línea simple → un proyecto puede existir sin empleados asignados
En notación de cardinalidad completa (min, max):
(1,1) → obligatorio, exactamente uno
(0,1) → opcional, como máximo uno
(1,N) → obligatorio, uno o más
(0,N) → opcional, cero o másEjemplo completo: sistema de tienda online paso a paso
Vamos a diseñar el diagrama ER de una tienda online sencilla. Primero identificamos los requisitos, luego las entidades, los atributos y finalmente las relaciones.
Paso 1: Identificar los requisitos
El sistema debe gestionar:
✓ Clientes que hacen pedidos
✓ Pedidos que contienen productos
✓ Productos que pertenecen a categorías
✓ Empleados que gestionan pedidosPaso 2: Identificar las entidades
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ CLIENTE │ │ PEDIDO │ │PRODUCTO │ │CATEGORÍA │ │EMPLEADO │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘Paso 3: Añadir atributos
CLIENTE: id_cliente*, nombre, email, telefono, ciudad
PEDIDO: id_pedido*, fecha, estado, total
PRODUCTO: id_producto*, nombre, descripcion, precio, stock
CATEGORÍA: id_categoria*, nombre
EMPLEADO: id_empleado*, nombre, cargo, email
(* = atributo clave / clave primaria)Paso 4: Identificar relaciones y cardinalidades
CLIENTE ──REALIZA── PEDIDO → 1:N (un cliente, muchos pedidos)
PEDIDO ──CONTIENE── PRODUCTO → N:M (muchos productos por pedido)
PRODUCTO ──PERTENECE── CATEGORÍA → N:1 (muchos productos, una categoría)
EMPLEADO ──GESTIONA── PEDIDO → 1:N (un empleado gestiona muchos pedidos)Paso 5: El diagrama ER completo
(nombre) (email) (telefono)
\ | /
(id_cliente*) |
\ |
┌──────────┐ 1 N ┌──────────┐
│ CLIENTE │────────◆REALIZA◆──────│ PEDIDO │
└──────────┘ └────┬─────┘
│(id_pedido*)
│(fecha)
N │(estado) 1
┌─────◆GESTIONA◆──────────────── ┌──────────┐
│ │EMPLEADO │
│ └──────────┘
┌────┘
┌────┴─────┐
│ PEDIDO │
└────┬─────┘
│ N
◆CONTIENE◆ ← (cantidad, precio_unitario)
│ M
┌────┴─────┐
│PRODUCTO │──────────◆PERTENECE◆──── ┌──────────┐
└──────────┘ N 1 │CATEGORÍA │
(id_producto*)(nombre) └──────────┘
(precio)(stock)💡 Nota sobre la relación CONTIENE: Como es N:M, tiene atributos propios: cantidad y precio_unitario. Estos atributos no pertenecen ni al PEDIDO ni al PRODUCTO por sí solos, sino a la relación entre ambos. Un mismo producto puede tener distintos precios en distintos pedidos.
De diagrama ER a tablas SQL — la transformación
El diagrama ER es conceptual. Para implementarlo en una base de datos real hay que transformarlo en tablas. Las reglas de transformación son sistemáticas.
Regla 1: Cada entidad fuerte → una tabla
-- CLIENTE
CREATE TABLE clientes (
id_cliente INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
telefono VARCHAR(20),
ciudad VARCHAR(50)
);
-- PRODUCTO
CREATE TABLE productos (
id_producto INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100) NOT NULL,
descripcion TEXT,
precio DECIMAL(10,2) NOT NULL,
stock INT DEFAULT 0,
id_categoria INT,
FOREIGN KEY (id_categoria) REFERENCES categorias(id_categoria)
);
-- CATEGORÍA
CREATE TABLE categorias (
id_categoria INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(50) NOT NULL
);
-- EMPLEADO
CREATE TABLE empleados (
id_empleado INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100) NOT NULL,
cargo VARCHAR(50),
email VARCHAR(100) UNIQUE
);
-- PEDIDO (relación 1:N con CLIENTE y EMPLEADO)
CREATE TABLE pedidos (
id_pedido INT PRIMARY KEY AUTO_INCREMENT,
fecha DATETIME DEFAULT CURRENT_TIMESTAMP,
estado ENUM('pendiente','procesando','enviado','entregado') DEFAULT 'pendiente',
total DECIMAL(10,2),
id_cliente INT NOT NULL,
id_empleado INT,
FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente),
FOREIGN KEY (id_empleado) REFERENCES empleados(id_empleado)
);Regla 2: Relación N:M → tabla intermedia
-- DETALLE_PEDIDOS (tabla intermedia para la relación N:M entre PEDIDO y PRODUCTO)
-- Los atributos de la relación (cantidad, precio_unitario) van aquí
CREATE TABLE detalle_pedidos (
id_pedido INT NOT NULL,
id_producto INT NOT NULL,
cantidad INT NOT NULL DEFAULT 1,
precio_unitario DECIMAL(10,2) NOT NULL,
PRIMARY KEY (id_pedido, id_producto), -- clave primaria compuesta
FOREIGN KEY (id_pedido) REFERENCES pedidos(id_pedido),
FOREIGN KEY (id_producto) REFERENCES productos(id_producto)
);Regla 3: Relación 1:1 → clave foránea en cualquiera de las dos
-- PERSONA y PASAPORTE (relación 1:1)
CREATE TABLE personas (
id_persona INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100)
);
CREATE TABLE pasaportes (
id_pasaporte INT PRIMARY KEY AUTO_INCREMENT,
numero VARCHAR(20) UNIQUE NOT NULL,
vencimiento DATE,
id_persona INT UNIQUE, -- UNIQUE garantiza la relación 1:1
FOREIGN KEY (id_persona) REFERENCES personas(id_persona)
);El resultado final — estructura completa
clientes pedidos detalle_pedidos productos
────────── ────────────── ─────────────── ──────────────
id_cliente PK id_pedido PK id_pedido PK FK id_producto PK
nombre fecha id_producto PK FK nombre
email estado cantidad descripcion
telefono total precio_unitario precio
ciudad id_cliente FK → ← conecta → stock
id_empleado FK id_categoria FK
↑
empleados categorias
────────── ──────────
id_empleado PK id_categoria PK
nombre nombre
cargo
emailLa notación Crow's Foot — la más usada en herramientas modernas
El Modelo ER original de Peter Chen usa rombos y óvalos. Pero en herramientas como Lucidchart, Draw.io, MySQL Workbench y dbdiagram.io verás con más frecuencia la notación Crow's Foot (pata de cuervo), que es más compacta y clara.
Notación Chen (original):
┌──────────┐ 1 N ┌──────────┐
│ CLIENTE │────────────│ PEDIDO │
└──────────┘ └──────────┘
Notación Crow's Foot (herramientas modernas):
┌──────────┐ ┌──────────┐
│ CLIENTE │──────────<{│ PEDIDO │
└──────────┘ └──────────┘
Símbolos Crow's Foot:
──│ exactamente uno (obligatorio)
──O cero (opcional)
──< muchos
──│O cero o uno (opcional)
──│< uno o más (obligatorio)
──O< cero o más (opcional)
Ejemplos:
A ──│────│O── B → A tiene exactamente un B (B es opcional)
A ──│────│<── B → A tiene uno o más B (obligatorio)
A ──O────O<── B → A tiene cero o más B (todo opcional)Errores comunes al diseñar diagramas ER
❌ Error 1: Confundir entidad con atributo
-- ❌ Mal diseño: "dirección" como entidad cuando debería ser atributo
┌──────────┐ ┌──────────┐
│ CLIENTE │─────────│DIRECCIÓN │ ← innecesario si solo es texto
└──────────┘ └──────────┘
-- ✅ Correcto: dirección como atributo de CLIENTE
CLIENTE: id_cliente, nombre, email, direccion
-- ✅ Excepción: dirección SERÍA entidad si necesitas guardar
-- múltiples datos de ella (calle, número, ciudad, CP...)
-- o si varios clientes pueden compartir la misma dirección❌ Error 2: Olvidar las tablas intermedias para relaciones N:M
-- ❌ Intentar implementar N:M directamente (imposible correctamente)
-- No hay forma limpia de guardar que un pedido tiene varios productos
-- sin crear la tabla detalle_pedidos
-- ✅ Siempre crear tabla intermedia para N:M
-- PEDIDO ←── detalle_pedidos ──→ PRODUCTO❌ Error 3: No definir correctamente la cardinalidad
-- Pregúntate SIEMPRE en ambas direcciones:
-- "¿Un CLIENTE puede tener cuántos PEDIDOS?" → muchos (N)
-- "¿Un PEDIDO puede pertenecer a cuántos CLIENTES?" → uno (1)
-- Resultado: CLIENTE 1:N PEDIDO❌ Error 4: No usar verbos descriptivos en las relaciones
-- ❌ Relaciones sin nombre claro
CLIENTE ──────────── PEDIDO
-- ✅ Verbos que describen la relación
CLIENTE ──REALIZA── PEDIDO
EMPLEADO ──GESTIONA── PEDIDO
PRODUCTO ──PERTENECE── CATEGORÍAHerramientas gratuitas para crear diagramas ER
- 🎨 Draw.io / diagrams.net (app.diagrams.net) — la más usada, gratuita, sin registro, guarda en Google Drive
- 🔷 dbdiagram.io (dbdiagram.io) — escribe el esquema en código y genera el diagrama automáticamente. Perfecta para desarrolladores
- 📊 Lucidchart — plan gratuito con hasta 3 diagramas, muy visual e intuitiva
- 🟠 MySQL Workbench — gratuita, genera el SQL automáticamente desde el diagrama visual
- 🌊 Miro — colaborativa en tiempo real, ideal para equipos
Resumen: lo que aprendiste hoy
- ✅ El Modelo ER fue creado por Peter Chen en 1976 y es el estándar para diseñar bases de datos
- ✅ Los 4 componentes son: entidad (rectángulo), atributo (óvalo), relación (rombo) y cardinalidad
- ✅ Las entidades fuertes existen por sí solas; las débiles dependen de otra entidad
- ✅ Los atributos pueden ser simples, clave, multivaluados o derivados
- ✅ Cardinalidad 1:1 (uno a uno), 1:N (uno a muchos) y N:M (muchos a muchos)
- ✅ Las relaciones N:M siempre necesitan una tabla intermedia en la implementación SQL
- ✅ La participación indica si la relación es obligatoria (total) u opcional (parcial)
- ✅ La notación Crow's Foot es la más usada en herramientas modernas
- ✅ El flujo es: requisitos → entidades → atributos → relaciones → cardinalidades → SQL
- ✅ Diseñar bien el ER antes de codificar ahorra horas de refactorización después
🧪 ¿Tienes bien sólidos los fundamentos de SQL para implementar tus diagramas ER?
Diseñar el modelo ER es el primer paso. Implementarlo correctamente en SQL requiere dominar claves primarias, claves foráneas, tipos de datos y consultas. Comprueba dónde estás:
👉 Test: SQL Básico 👉 Test: SQL vs NoSQL
¿Cuál fue el concepto que más te costó entender: la cardinalidad, las entidades débiles o la transformación de relaciones N:M a tablas? ¿Ya habías visto un diagrama ER antes? Cuéntanos en los comentarios 👇 — respondemos todos. 🚀
Alex
4 months ago