Editor de diagramas ER Mermaid
Un diagrama entidad-relación muestra tablas, sus columnas y cómo se unen. Sirve cuando el asunto es un esquema de base de datos y lo interesante son las claves y la cardinalidad — uno a muchos, opcional, o a través de una tabla intermedia. Para tipos con comportamiento y herencia, usa un diagrama de clases.
Un esquema de pedidos normalizado con tabla intermedia
La parte que merece estudio es el `}o--||` de LINEA_PEDIDO: así se expresa con honestidad una relación de muchos a muchos, a través de una tabla intermedia con columnas propias, en lugar de fingir que dos tablas se conectan directamente. Guardar el precio en la línea y no solo en el artículo es la decisión que el diagrama debe dejar ver.
erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"
PEDIDO ||--|{ LINEA_PEDIDO : "contiene"
ARTICULO ||--o{ LINEA_PEDIDO : "aparece en"
CLIENTE ||--o{ DIRECCION : "envía a"
CLIENTE {
int id PK
string correo UK "se guarda en minúsculas"
string nombre
datetime alta
}
PEDIDO {
int id PK
int cliente_id FK
string estado
decimal importe_total
}
LINEA_PEDIDO {
int pedido_id PK, FK
int articulo_id PK, FK
int cantidad
decimal precio_unitario "precio en el momento del pedido"
}
ARTICULO {
int id PK
string referencia UK
string nombre
}
DIRECCION {
int id PK
int cliente_id FK
string codigo_postal
}Ejemplos resueltos
1. Dos entidades y una relación
Toda relación ER necesita una etiqueta después de los dos puntos: no es opcional, al contrario que en una arista de diagrama de flujo. Se lee como una frase: CLIENTE realiza PEDIDO.
erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"2. Añadir columnas
Cada línea de atributo es `tipo nombre`, y las dos partes son obligatorias. `PK`, `FK` y `UK` marcan claves; una cadena entrecomillada al final es un comentario.
erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"
CLIENTE {
int id PK
string correo UK
string nombre
}
PEDIDO {
int id PK
int cliente_id FK
datetime fecha "en UTC"
}3. Cardinalidad que dice algo
Los dos caracteres más cercanos a cada entidad son su cardinalidad. Este ejemplo dice que un pedido tiene que tener al menos una línea, pero que un cliente puede no tener ningún pedido: una restricción real que el esquema debería imponer y el diagrama debería mostrar.
erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"
PEDIDO ||--|{ LINEA_PEDIDO : "contiene"
LINEA_PEDIDO }o--|| ARTICULO : "referencia"4. Muchos a muchos con tabla intermedia
Mermaid puede dibujar un muchos a muchos directo, pero un esquema casi nunca lo tiene: debajo hay una tabla intermedia. Dibujarla es más honesto y te da dónde poner las columnas que pertenecen a la relación misma.
erDiagram
ALUMNO ||--o{ MATRICULA : "se apunta a"
ASIGNATURA ||--o{ MATRICULA : "se cursa mediante"
MATRICULA {
int alumno_id PK, FK
int asignatura_id PK, FK
datetime fecha_matricula
string nota "nula hasta la evaluación"
}
ALUMNO {
int id PK
string nombre
}
ASIGNATURA {
int id PK
string codigo UK
}5. Relaciones reflexivas
Una tabla puede relacionarse consigo misma: una línea jerárquica, un árbol de categorías, un hilo de comentarios. Aquí la etiqueta de la relación importa más que de costumbre, porque los dos extremos son la misma entidad.
erDiagram
EMPLEADO ||--o{ EMPLEADO : "dirige a"
EMPLEADO {
int id PK
int jefe_id FK "nulo para la dirección general"
string nombre
string puesto
}Referencia de sintaxis del diagrama ER
La cardinalidad se escribe con dos caracteres en cada extremo de la relación y se lee desde el centro hacia fuera. El par de la izquierda describe la entidad de la izquierda; el de la derecha, la de la derecha.
| Sintaxis | Significado |
|---|---|
| erDiagram | Abre el diagrama. Distingue mayúsculas: `erdiagram` no vale. |
| A ||--o{ B : "etiqueta" | Relación. La etiqueta es obligatoria. |
| || | Exactamente uno. |
| o| | Cero o uno. |
| }| | Uno o más. |
| }o | Cero o más. |
| -- | Relación identificadora — línea continua. |
| .. | Relación no identificadora — línea discontinua. |
| A { ... } | Bloque de atributos de la entidad A. |
| int id PK | Atributo: tipo, luego nombre, luego marca de clave opcional. |
| PK / FK / UK | Clave primaria, ajena y única. |
| int id PK, FK | Varias marcas de clave, separadas por comas. |
| string correo "comentario" | La cadena entrecomillada final es un comentario de columna. |
| A ||--o{ B : "pertenece a" | Las comillas son OBLIGATORIAS en cuanto la etiqueta lleve un espacio. Sin ellas se corta en el primer espacio y cada palabra restante se convierte en una entidad fantasma. |
Seis errores que rompen un diagrama ER
El ER tiene la gramática más estricta de los seis tipos: cosas que en otros diagramas pasan sin problema aquí se rechazan de plano. Pero también tiene el fallo silencioso que más castiga a quien escribe en español. Todo reproducido con Mermaid 11.12.2.
Lo que ves
Se dibuja, pero la etiqueta sale cortada y aparecen entidades que no habías escrito
Por qué
Una etiqueta de relación con espacios y sin comillas. Este es el fallo que más va a molestarte escribiendo en español, porque casi todos nuestros verbos de relación llevan preposición: «pertenece a», «se apunta a», «aparece en». Medido: `CLIENTE ||--o{ PEDIDO : pertenece a` no da ningún error, recorta la etiqueta a «pertenece» y crea una entidad fantasma llamada «a». Con tres palabras salen dos entidades fantasma. Dos tablas se convierten en cuatro cajas y nada te avisa.
Solución
Entrecomilla toda etiqueta que lleve un espacio. En español eso significa entrecomillarlas prácticamente siempre; es más fácil adoptarlo como norma que ir decidiendo caso por caso.
erDiagram
CLIENTE ||--o{ PEDIDO : pertenece aerDiagram
CLIENTE ||--o{ PEDIDO : "pertenece a"Lo que ves
Parse error, termina en: Expecting 'COLON', 'STYLE_SEPARATOR', got 'NEWLINE'
Por qué
Una relación sin etiqueta. A diferencia de una arista de diagrama de flujo, los dos puntos y la etiqueta son obligatorios: sin ellos la línea simplemente termina antes de tiempo.
Solución
Añade los dos puntos y un sintagma verbal, entrecomillado si lleva espacios.
erDiagram
CLIENTE ||--o{ PEDIDOerDiagram
CLIENTE ||--o{ PEDIDO : "realiza"Lo que ves
Parse error, termina en: got 'UNICODE_TEXT'
Por qué
Un token de cardinalidad inválido. Solo valen `||`, `o|`, `}|` y `}o` (y sus reflejos); cualquier otra cosa falla. `oo` es la errata habitual, por esperar que la notación sea simétrica.
Solución
Usa uno de los cuatro pares. `||--o{` — exactamente uno a cero o más — cubre la mayoría de las claves ajenas.
erDiagram
CLIENTE ||--oo{ PEDIDO : "realiza"erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"Lo que ves
Parse error, termina en: Expecting 'ATTRIBUTE_WORD', got 'BLOCK_STOP'
Por qué
Un atributo con nombre pero sin tipo. Los atributos ER son `tipo nombre`, y el tipo no es opcional, cosa que sorprende a quien viene de bases de datos sin esquema.
Solución
Dale un tipo a cada atributo. Invéntalo si el esquema real no lo tiene: `string`, `int`, `json`.
erDiagram
CLIENTE {
correo
}erDiagram
CLIENTE {
string correo
}Lo que ves
Parse error, termina en: Expecting 'NON_IDENTIFYING', 'IDENTIFYING', got 'UNICODE_TEXT'
Por qué
La línea entre las dos marcas de cardinalidad está mal. Tiene que ser exactamente de dos caracteres: `--` para una relación identificadora o `..` para una no identificadora. Un solo guion no es una versión corta de `--`, es un error de sintaxis.
Solución
Usa `--` o `..` entre los pares de cardinalidad.
erDiagram
CLIENTE ||-o{ PEDIDO : "realiza"erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"Lo que ves
La cardinalidad se dibuja, pero describe la restricción contraria
Por qué
Los dos caracteres más cercanos a cada entidad pertenecen a esa entidad, y es facilísimo leerlos al revés. `CLIENTE ||--o{ PEDIDO` dice que un cliente tiene cero o más pedidos. Dale la vuelta a `CLIENTE }o--|| PEDIDO` y habrás afirmado que todo cliente pertenece a exactamente un pedido, que no tiene sentido — y se dibuja sin protestar.
Solución
Lee desde el centro hacia fuera: las marcas que tocan a CLIENTE describen cuántos clientes hay, no cuántos pedidos.
erDiagram
CLIENTE }o--|| PEDIDO : "realiza"erDiagram
CLIENTE ||--o{ PEDIDO : "realiza"Notas sobre el dibujado
Medido sobre el Mermaid 11.12.2 que usa este sitio.
La disposición la marcan las relaciones, no el número de entidades
Una cadena de entidades relacionadas una tras otra se dibuja como una columna alta: cuarenta entidades dan un viewBox de unos 116×7315, frente a 116×470 con tres. Pero esas mismas cuarenta entidades relacionadas con una única tabla central producen algo mucho más ancho y bajo. Es el único tipo de diagrama de aquí donde la forma de tus datos cambia la forma del dibujo más que su tamaño, así que un esquema que no cabe se arregla más a menudo cambiando qué relaciones dibujas que cuántas.
Casi todas las etiquetas en español necesitan comillas
Vale la pena insistir porque es el fallo silencioso más caro de esta página. Las etiquetas de relación en inglés suelen ser una palabra — places, contains, references —, así que en la documentación inglesa las comillas parecen un adorno. En español la mayoría son sintagmas con preposición y sin comillas se rompen. La norma práctica: entrecomilla siempre la etiqueta, y no tendrás que pensarlo.
Los nombres de entidad distinguen mayúsculas y por convención van en mayúsculas
`CLIENTE` y `cliente` son dos entidades distintas, y mencionar las dos en el mismo diagrama te da dos cajas sin avisar. La convención de las mayúsculas no la impone Mermaid, pero merece la pena mantenerla justamente porque hace evidente cualquier referencia en minúsculas escrita por descuido. Los acentos funcionan sin problema en nombres de entidad y de columna, comprobado con `ARTÍCULO` y `descripción`; lo que sí conviene es decidir de entrada si el esquema lleva tildes o no y no mezclar.
La gramática es la más estricta de los seis tipos
Las etiquetas de relación son obligatorias, los tipos de atributo también, y los tokens de cardinalidad son un conjunto cerrado. Comparado con el Gantt, donde casi todo se dibuja y los fallos son silenciosos, el ER falla pronto y en voz alta. Eso es una virtud: si un diagrama ER se dibuja, es bastante probable que sea el que querías, con la excepción notable de las etiquetas sin comillas.
Las etiquetas son HTML, así que la exportación a PNG redibuja
Las tablas de atributos se dibujan dentro de un `<foreignObject>` del SVG, así que los navegadores no pueden rasterizarlas directamente sobre un canvas. La exportación a PNG de este sitio devolvía antes un fichero SVG en silencio; ahora redibuja primero con etiquetas de texto SVG plano y produce un PNG correcto y a tamaño completo, con una tipografía apenas distinta.
Cuándo conviene otro diagrama
Si necesitas herencia, interfaces o métodos, este es el diagrama equivocado: el ER no tiene ninguno de esos conceptos. Usa un diagrama de clases y asume que modela tu código y no tus tablas.
Si el esquema es grande, un ER de todo el esquema es un mural que nadie lee. Dibuja las cinco tablas implicadas en lo que estás explicando y deja fuera el resto; un diagrama es un argumento, no un inventario.
Y si la pregunta real es cómo se mueven los datos entre sistemas y no cómo se almacenan, un diagrama de flujo con un subgrafo por sistema la responderá y un ER no.
Otros tipos de diagrama
Escrito por Dominik Malsch · Última actualización: