Diagramma ER
Il diagramma entità-relazione (in breve diagramma ER) descrive cose di interesse correlate tra loro all'interno di un determinato dominio di conoscenza. Un diagramma ER di base è composto da tipi di entità (usati per classificare le cose di interesse) e specifica le relazioni che possono esistere tra le entità (istanze di questi tipi di entità),Nota che nella pratica reale dei diagrammi ER il 'tipo di entità' viene quasi sempre chiamato semplicemente 'entità'. Ad esempio, il 'tipo di entità CUSTOMER' viene di solito chiamato direttamente 'entità CUSTOMER'. Questa pratica è molto diffusa, quindi se ne sconsigliano altre; tecnicamente, tuttavia, un'entità è un'istanza astratta di un tipo di entità, e il diagramma ER mostra proprio queste istanze astratte e le relazioni tra esse. Ecco perché le entità sono sempre nominate al singolare.
Copia
Incorpora
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
I nomi delle entità sono di solito in maiuscolo, anche se non esiste uno standard universalmente riconosciuto per questo e la sintassi di Mermaid non lo impone.
Le relazioni tra le entità sono rappresentate da linee con marcatori alle estremità che indicano la cardinalità. Mermaid usa la diffusissima notazione a piede di corvo; il piede di corvo indica visivamente che l'entità a cui è collegato può avere più istanze.
I diagrammi ER possono essere usati per vari scopi, da un modello logico astratto che non contiene alcun dettaglio implementativo, fino al modello fisico delle tabelle di un database relazionale. Includere le definizioni degli attributi in un diagramma ER aiuta a comprendere lo scopo e il significato delle entità; queste definizioni di attributi non devono essere esaustive, di solito è sufficiente una piccola parte degli attributi. Mermaid permette di definirli con il loro tipo e nome.
Copia
Incorpora
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
}
Quando includi attributi in un diagramma ER, devi decidere se includere le chiavi esterne come attributi; ciò può dipendere da quanto desideri rappresentare la struttura delle tabelle relazionali. Se il tuo diagramma è un modello logico e non intende suggerire un'implementazione relazionale, allora è meglio non includere questi attributi, poiché la relazione esprime già come le entità sono associate tra loro. Ad esempio, una struttura dati JSON può usare un array per implementare una relazione uno-a-molti senza attributi di chiave esterna. Analogamente, i linguaggi di programmazione orientati agli oggetti possono usare puntatori o riferimenti a collezioni. Anche per i modelli pensati per un'implementazione relazionale, si può ritenere che includere gli attributi di chiave esterna ripeta le informazioni già mostrate dalla relazione e non aggiunga significato all'entità.
Sintassi
Entità e relazioni
La sintassi Mermaid del diagramma ER è compatibile con PlantUML e la estende con funzionalità per etichettare le relazioni. Ogni istruzione comprende quanto segue:
Copia
Incorpora
<first-entity> [<relationship> <second-entity> : <relationship-label>]
- first-entity è il nome della prima entità. Il nome supporta qualsiasi carattere Unicode e, se racchiuso tra virgolette doppie, può contenere spazi.
- relationship descrive la relazione reciproca tra le due entità.
- second-entity è il nome dell'altra entità.
- relationship-label descrive la relazione dal punto di vista della prima entità.
Ad esempio:
Copia
Incorpora
PROPERTY ||--|{ ROOM : contains
Questa dichiarazione può essere interpretata come: una proprietà contiene una o più stanze, e una stanza appartiene a una sola proprietà. Qui l'etichetta è vista dal punto di vista della prima entità: una proprietà contiene una stanza, ma una stanza non contiene una proprietà. Dal punto di vista della seconda entità, l'etichetta equivalente è di solito facile da dedurre.
Solo la parte first-entity è obbligatoria. Questo permette di mostrare entità senza relazioni, il che è molto utile quando si costruisce un diagramma in modo iterativo. Se vengono specificate altre parti dell'istruzione, allora tutte le parti sono obbligatorie.
Testo Unicode
Nomi di entità, relazioni e attributi supportano tutti testo unicode.
Copia
Incorpora
erDiagram
"This ❤ Unicode"
Sintassi delle relazioni
La parte relativa alla relazione di ogni istruzione può essere suddivisa in tre sottoparti:
- La cardinalità della prima entità rispetto alla seconda entità
- Se la relazione conferisce o meno identità all'entità figlia
- La cardinalità della seconda entità rispetto alla prima entità
La cardinalità è una proprietà che descrive il numero di elementi di un'altra entità che possono essere associati all'entità in questione. Nell'esempio sopra, una PROPERTY può essere associata a una o più istanze di ROOM, mentre una ROOM può essere associata a una sola PROPERTY. Ogni marcatore di cardinalità contiene due caratteri: il carattere più esterno rappresenta il valore massimo, quello più interno il valore minimo. La tabella seguente riassume le possibilità di cardinalità:
| Valore (sinistra) | Valore (destra) | Significato |
|---|---|---|
| |o | o| | Zero o uno |
| || | || | Esattamente uno |
| }o | o{ | Zero o più (senza limite) |
| }| | |{ | Uno o più (senza limite) |
| Valore (sinistra) | Valore (destra) | Significato |
|---|---|---|
| one or zero | one or zero | Zero o uno |
| zero or one | zero or one | Zero o uno |
| one or more | one or more | Uno o più |
| one or many | one or many | Uno o più |
| many(1) | many(1) | Uno o più |
| 1+ | 1+ | Uno o più |
| zero or more | zero or more | Zero o più |
| zero or many | zero or many | Zero o più |
| many(0) | many(0) | Zero o più |
| 0+ | 0+ | Zero o più |
| only one | only one | Esattamente uno |
| 1 | 1 | Esattamente uno |
Identificazione
Le relazioni possono essere classificate come identificanti e non identificanti, e sono renderizzate rispettivamente con una linea continua o tratteggiata. Questo è importante quando una delle entità non può esistere autonomamente senza l'altra. Ad esempio, una compagnia che offre assicurazioni per persone che guidano automobili potrebbe avere bisogno di memorizzare i dati di NAMED-DRIVER. In fase di modellazione, potremmo innanzitutto osservare che una CAR può essere guidata da molte PERSON, e una PERSON può guidare molte CAR; entrambe possono esistere senza l'altra, quindi questa è una relazione non identificante, che possiamo specificare in Mermaid come: PERSON }|..|{ CAR : "driver". Nota i due punti al centro della relazione: questo porta a tracciare una linea tratteggiata tra le due entità. Tuttavia, quando questa relazione molti-a-molti viene risolta in due relazioni uno-a-molti, osserviamo che NAMED-DRIVER non potrebbe esistere senza PERSON e CAR. Queste relazioni diventano relazioni identificanti e sono indicate con un trattino, corrispondente a una linea continua:
| Valore | Alias |
|---|---|
| -- | Identificante |
| .. | Non identificante |
| Valore | 别名为 |
|---|---|
| to | Identificante |
| optionally to | Non identificante |
Copia
Incorpora
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o..o{ NAMED-DRIVER : is
Copia
Incorpora
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o--o{ NAMED-DRIVER : is
Attributo
Puoi definire gli attributi di un'entità specificando il nome dell'entità seguito da un blocco contenente più type name, dove il blocco è racchiuso tra parentesi graffe {}. Gli attributi vengono mostrati all'interno del riquadro dell'entità, ad esempio:
Copia
Incorpora
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
}
Il valore di type deve iniziare con un carattere alfabetico e può contenere numeri, trattini, underscore, parentesi tonde e parentesi quadre. Il valore di name segue un formato simile a type, ma può anche iniziare con un asterisco, come ulteriore opzione per indicare che la proprietà è una chiave primaria. A parte questo, non ci sono altre restrizioni né un insieme implicito di tipi di dati validi.
Alias dell'entità
Puoi aggiungere un alias a un'entità usando le parentesi quadre. Se viene fornito un alias, nel diagramma verrà mostrato l'alias invece del nome dell'entità; l'alias segue tutte le stesse regole del nome dell'entità.
Copia
Incorpora
erDiagram
p[Person] {
string firstName
string lastName
}
a["Customer Account"] {
string email
}
p ||--o| a : has
Chiavi e commenti degli attributi
Gli attributi possono anche definire chiavi o commenti. Le chiavi possono essere chiave primaria (PK), chiave esterna (FK) o chiave unica (UK). Per specificare più vincoli di chiave su un singolo attributo, separali con virgole (ad esempio, PK, FK). I commenti sono definiti da virgolette doppie alla fine dell'attributo; il commento non può contenere il carattere virgoletta doppia.
Copia
Incorpora
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
Direzione
L'istruzione di direzione dichiara la direzione del diagramma.
TB dichiara che la direzione del diagramma è dall'alto verso il basso; BT può invertirla in dal basso verso l'alto.
Copia
Incorpora
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 dichiara che la direzione del diagramma è da sinistra verso destra; RL può invertirla in da destra verso sinistra.
Copia
Incorpora
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
}
Impostare lo stile dei nodi
Puoi applicare uno stile specifico a un nodo, ad esempio un bordo più spesso o un colore di sfondo diverso.
Copia
Incorpora
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
Puoi anche allegare uno stile a un elenco di nodi in un'unica istruzione:
Copia
Incorpora
style nodeId1,nodeId2 styleList
Classe
Più comodo che definire lo stile ogni volta è definire una classe di stile e applicarla ai nodi che devono avere un aspetto diverso.
La definizione della classe è mostrata nell'esempio seguente:
Copia
Incorpora
classDef className fill:pink,stroke:#333,stroke-width:4px
Puoi anche definire più classi in un'unica istruzione:
Copia
Incorpora
classDef firstClassName,secondClassName font-size:12pt
La sintassi per allegare una classe a un nodo è la seguente:
Copia
Incorpora
class nodeId1 className
Puoi anche allegare una classe a un elenco di nodi in un'unica istruzione:
Copia
Incorpora
class nodeId1,nodeId2 className
È anche possibile allegare più classi contemporaneamente:
Copia
Incorpora
class nodeId1,nodeId2 className1,className2
Un modo semplice per aggiungere una classe è usare l'operatore ::: per allegare il nome della classe a un nodo, come mostrato di seguito:
Copia
Incorpora
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
Per dichiarare la relazione tra entità puoi usare la seguente sintassi:
Copia
Incorpora
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
In modo simile all'istruzione class, la sintassi abbreviata può applicare più classi in una volta:
Copia
Incorpora
nodeId:::className1,className2
Classe predefinita
Se una classe è chiamata default, verrà assegnata a tutte le classi che non hanno una definizione di classe specifica.
Copia
Incorpora
classDef default fill:pink,stroke:#333,stroke-width:4px;
Nota: gli stili personalizzati provenienti da uno stile o da altre istruzioni di classe hanno la precedenza e sovrascrivono lo stile predefinito. (Ad esempio, la classe default imposta uno sfondo rosa per i nodi, ma se si applica la classe blue, il nodo avrà un colore di sfondo blu.)
Copia
Incorpora
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
Configurazione
Layout
Il layout del diagramma è gestito da render(); il layout predefinito è il layout ELK, adatto a diagrammi più grandi e complessi.
Per usare invece il classico layout Dagre, puoi impostarlo nel config del frontmatter YAML
Copia
Incorpora
---
config:
layout: dagre
---
Il contenuto del codice Mermaid è il seguente:
Copia
Incorpora
---
title: Order example
config:
layout: elk
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses