Diagrama ER
El diagrama de entidad-relación (abreviado diagrama ER) describe cosas de interés interrelacionadas dentro de un campo de conocimiento concreto. Un diagrama ER básico se compone de tipos de entidad (que clasifican las cosas de interés) y especifica las relaciones que pueden existir entre entidades (instancias de esos tipos de entidad),Ten en cuenta que, en la práctica con diagramas ER, casi siempre se abrevia 'tipo de entidad' como 'entidad'. Por ejemplo, 'el tipo de entidad CUSTOMER' suele llamarse directamente 'la entidad CUSTOMER'. Esta práctica es tan común que no se recomienda usar otras formas, pero técnicamente una entidad es una instancia abstracta de un tipo de entidad, y el diagrama ER muestra precisamente esas instancias abstractas y las relaciones entre ellas. Por eso las entidades siempre se nombran con sustantivos en singular.
Copiar
Insertar
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
Los nombres de entidad normalmente van en mayúsculas, aunque no hay un estándar reconocido para ello y la sintaxis de Mermaid tampoco lo exige.
Las relaciones entre entidades se representan con líneas cuyos extremos llevan marcadores que indican la cardinalidad. Mermaid usa el símbolo de pata de gallo, el más popular; la pata de gallo indica visualmente que la entidad a la que está conectada puede tener varias instancias.
Los diagramas ER pueden usarse para diversos fines, desde un modelo lógico abstracto que no contiene ningún detalle de implementación hasta el modelo físico de las tablas de una base de datos relacional. Incluir definiciones de atributos en el diagrama ER ayuda a entender el propósito y el significado de las entidades; estas definiciones de atributos no tienen por qué ser exhaustivas, normalmente basta con una pequeña parte de los atributos. Mermaid permite definirlos con su tipo y su nombre.
Copiar
Insertar
erDiagram
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
Al incluir atributos en un diagrama ER, debes decidir si incluir las claves foráneas como atributos, lo que puede depender de hasta qué punto quieres representar la estructura de las tablas relacionales. Si tu gráfico es un modelo lógico y no pretende sugerir una implementación relacional, es mejor no incluir esos atributos, ya que la relación de asociación ya comunica cómo se asocian las entidades. Por ejemplo, una estructura de datos JSON puede implementar una relación uno a muchos usando matrices sin atributos de clave foránea. De forma similar, un lenguaje de programación orientado a objetos puede usar punteros o referencias a colecciones. Incluso para los modelos destinados a una implementación relacional, puede considerarse que incluir atributos de clave foránea repetiría la información que muestra la relación y no añadiría significado a la entidad.
Sintaxis
Entidades y relaciones
La sintaxis de Mermaid para el diagrama ER es compatible con PlantUML y amplía la funcionalidad para etiquetar relaciones. Cada sentencia incluye lo siguiente:
Copiar
Insertar
<first-entity> [<relationship> <second-entity> : <relationship-label>]
- first-entity es el nombre de la primera entidad. El nombre admite cualquier carácter Unicode y, si se encierra entre comillas dobles, puede contener espacios.
- relationship describe la relación mutua entre dos entidades.
- second-entity es el nombre de la otra entidad.
- relationship-label describe la relación desde el punto de vista de la primera entidad.
Por ejemplo:
Copiar
Insertar
PROPERTY ||--|{ ROOM : contains
Esta declaración puede entenderse así: una propiedad contiene una o varias habitaciones, y una habitación pertenece a una sola propiedad. Aquí la etiqueta se plantea desde el punto de vista de la primera entidad: una propiedad contiene una habitación, pero una habitación no contiene propiedades. Desde el punto de vista de la segunda entidad, la etiqueta equivalente suele deducirse con facilidad.
Solo la parte first-entity es obligatoria. Esto permite mostrar entidades sin relaciones, lo que resulta muy útil al construir el gráfico de forma iterativa. Si se especifica alguna otra parte de la sentencia, entonces todas las partes son obligatorias.
Texto Unicode
Los nombres de entidad, las relaciones y los atributos admiten texto unicode.
Copiar
Insertar
erDiagram
"This ❤ Unicode"
Sintaxis de relaciones
La parte de relación de cada sentencia puede dividirse en tres subpartes:
- La cardinalidad de la primera entidad respecto a la segunda entidad
- Si la relación otorga identificación a la entidad secundaria
- La cardinalidad de la segunda entidad respecto a la primera entidad
La cardinalidad es una propiedad que describe la cantidad de elementos de otra entidad que pueden asociarse con la entidad en cuestión. En el ejemplo anterior, una PROPERTY puede asociarse con una o varias instancias de ROOM, mientras que un ROOM solo puede asociarse con una PROPERTY. Cada marcador de cardinalidad tiene dos caracteres: el carácter más externo representa el valor máximo y el más interno el valor mínimo. La siguiente tabla resume las posibilidades de cardinalidad:
| Valor (izquierda) | Valor (derecha) | Significado |
|---|---|---|
| |o | o| | Cero o uno |
| || | || | Exactamente uno |
| }o | o{ | Cero o más (sin límite) |
| }| | |{ | Uno o más (sin límite) |
| Valor (izquierda) | Valor (derecha) | Significado |
|---|---|---|
| one or zero | one or zero | Cero o uno |
| zero or one | zero or one | Cero o uno |
| one or more | one or more | Uno o más |
| one or many | one or many | Uno o más |
| many(1) | many(1) | Uno o más |
| 1+ | 1+ | Uno o más |
| zero or more | zero or more | Cero o más |
| zero or many | zero or many | Cero o más |
| many(0) | many(0) | Cero o más |
| 0+ | 0+ | Cero o más |
| only one | only one | Exactamente uno |
| 1 | 1 | Exactamente uno |
Identificación
Las relaciones pueden ser identificativas o no identificativas, y se renderizan con línea continua o discontinua respectivamente. Esto es importante cuando una de las entidades no puede existir de forma independiente sin la otra. Por ejemplo, una empresa que ofrece seguros para que las personas conduzcan coches podría necesitar almacenar los datos de NAMED-DRIVER. Al modelar, podríamos observar primero que un CAR puede ser conducido por muchas PERSON y que una PERSON puede conducir muchos CAR; ambas pueden existir sin la otra, por lo que se trata de una relación no identificativa, que podemos especificar en Mermaid como: PERSON }|..|{ CAR : "driver". Fíjate en los dos puntos en medio de la relación, lo que hará que se dibuje una línea discontinua entre las dos entidades. Sin embargo, cuando esta relación de muchos a muchos se resuelve en dos relaciones de uno a muchos, observamos que NAMED-DRIVER no podría existir sin PERSON y CAR. Estas relaciones se convierten en identificativas y se representan con guion, lo que corresponde a una línea continua:
| Valor | Alias |
|---|---|
| -- | Identificativa |
| .. | No identificativa |
| Valor | 别名为 |
|---|---|
| to | Identificativa |
| optionally to | No identificativa |
Copiar
Insertar
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o..o{ NAMED-DRIVER : is
Copiar
Insertar
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o--o{ NAMED-DRIVER : is
Atributo
Puedes definir atributos para una entidad especificando el nombre de la entidad y, a continuación, un bloque que contenga varios type name, donde el bloque va encerrado entre llaves {}. Los atributos se muestran dentro del recuadro de la entidad, por ejemplo:
Copiar
Insertar
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string firstName
string lastName
int age
}
El valor type debe comenzar por un carácter alfabético y puede contener números, guiones, guiones bajos, paréntesis y corchetes. El valor name sigue un formato similar a type, pero también puede comenzar por un asterisco, como otra opción para indicar que el atributo es una clave primaria. Aparte de esto, no hay otras restricciones ni un conjunto implícito de tipos de datos válidos.
Alias de entidad
Puedes añadir un alias a la entidad usando corchetes. Si se proporciona un alias, el gráfico mostrará el alias en lugar del nombre de la entidad; el alias sigue todas las mismas reglas que el nombre de la entidad.
Copiar
Insertar
erDiagram
p[Person] {
string firstName
string lastName
}
a["Customer Account"] {
string email
}
p ||--o| a : has
Claves y comentarios de atributos
Los atributos también pueden definir claves o comentarios. La clave puede ser clave primaria (PK), clave foránea (FK) o clave única (UK). Para especificar varias restricciones de clave en un solo atributo, sepáralas con comas (por ejemplo, PK, FK). El comentario se define con comillas dobles al final del atributo; el comentario no puede contener el carácter de comillas dobles.
Copiar
Insertar
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber PK
string make
string model
string[] parts
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string driversLicense PK "The license #"
string(99) firstName "Only 99 characters are allowed"
string lastName
string phone UK
int age
}
NAMED-DRIVER {
string carRegistrationNumber PK, FK
string driverLicence PK, FK
}
MANUFACTURER ||--o{ CAR : makes
Dirección
La sentencia de dirección declara la dirección del gráfico.
TB declara que la dirección del gráfico es de arriba hacia abajo; BT puede invertirla a de abajo hacia arriba.
Copiar
Insertar
erDiagram
direction TB
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
LR declara que la dirección del gráfico es de izquierda a derecha; RL puede invertirla a de derecha a izquierda.
Copiar
Insertar
erDiagram
direction LR
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
Establecer el estilo del nodo
Puedes aplicar un estilo específico a un nodo, como un borde más grueso o un color de fondo diferente.
Copiar
Insertar
erDiagram
id1||--||id2 : label
style id1 fill:pink,stroke:yellow,stroke-width:4px
style id2 fill:#69d,stroke:#f96,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
También puedes adjuntar estilos a una lista de nodos en una sola sentencia:
Copiar
Insertar
style nodeId1,nodeId2 styleList
Clase
Es más cómodo que definir el estilo cada vez: define una clase de estilo y adjúntala a los nodos que necesiten una apariencia diferente.
La definición de clase es como en el siguiente ejemplo:
Copiar
Insertar
classDef className fill:pink,stroke:#333,stroke-width:4px
También puedes definir varias clases en una sola sentencia:
Copiar
Insertar
classDef firstClassName,secondClassName font-size:12pt
La sintaxis para adjuntar una clase a un nodo es la siguiente:
Copiar
Insertar
class nodeId1 className
También puedes adjuntar una clase a una lista de nodos en una sola sentencia:
Copiar
Insertar
class nodeId1,nodeId2 className
También puedes adjuntar varias clases a la vez:
Copiar
Insertar
class nodeId1,nodeId2 className1,className2
Una forma sencilla de añadir clases es usar el operador ::: para adjuntar el nombre de la clase al nodo, como se muestra a continuación:
Copiar
Insertar
erDiagram
direction TB
CAR:::someclass {
string registrationNumber
string make
string model
}
PERSON:::someclass {
string firstName
string lastName
int age
}
HOUSE:::someclass
classDef someclass fill:#f96
Puedes declarar relaciones entre entidades con la siguiente sintaxis:
Copiar
Insertar
erDiagram
CAR {
string registrationNumber
string make
string model
}
PERSON {
string firstName
string lastName
int age
}
PERSON:::foo ||--|| CAR : owns
PERSON o{--|| HOUSE:::bar : has
classDef foo stroke:#f00
classDef bar stroke:#0f0
classDef foobar stroke:#00f
Al igual que la sentencia class, la sintaxis abreviada también puede aplicar varias clases a la vez:
Copiar
Insertar
nodeId:::className1,className2
Clase predeterminada
Si una clase se llama default, se asignará a todas las clases que no tengan una definición de clase específica.
Copiar
Insertar
classDef default fill:pink,stroke:#333,stroke-width:4px;
Nota: los estilos personalizados procedentes de estilos u otras sentencias de clase tienen prioridad y sobrescriben el estilo predeterminado. (Por ejemplo, la clase default establece un fondo rosa para un nodo, pero si se aplica la clase blue, se dará a ese nodo un color de fondo azul.)
Copiar
Insertar
erDiagram
CAR {
string registrationNumber
string make
string model
}
PERSON {
string firstName
string lastName
int age
}
PERSON:::foo ||--|| CAR : owns
PERSON o{--|| HOUSE:::bar : has
classDef default fill:pink,stroke-width:4px
classDef foo stroke:#f90
classDef bar stroke:#ff0
classDef foobar stroke:#69f
Configuración
Diseño
El diseño del gráfico lo gestiona render(); el diseño predeterminado es el diseño ELK, adecuado para gráficos más grandes y complejos.
Para usar en su lugar el diseño clásico de Dagre, puedes configurarlo en config del frontmatter de YAML
Copiar
Insertar
---
config:
layout: dagre
---
El contenido del código de Mermaid es el siguiente:
Copiar
Insertar
---
title: Order example
config:
layout: elk
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses