Diagramme ER
Le diagramme entité-relation (abrégé diagramme ER) décrit des objets d'intérêt interconnectés dans un domaine de connaissance donné. Un diagramme ER de base est composé de types d'entités (qui servent à classer les objets d'intérêt) et spécifie les relations qui peuvent exister entre les entités (les instances de ces types d'entités),Veuillez noter que dans la pratique, dans un diagramme ER, on abrège presque toujours « type d'entité » en « entité ». Par exemple, « le type d'entité CUSTOMER » sera généralement simplement appelé « l'entité CUSTOMER ». Cette pratique est très répandue, il est donc déconseillé de procéder autrement ; mais techniquement, une entité est une instance abstraite d'un type d'entité, et les diagrammes ER montrent précisément ces instances abstraites et leurs relations. C'est pourquoi les entités sont toujours nommées au singulier.
Copier
Intégrer
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
Les noms d'entités sont généralement en majuscules, bien qu'il n'existe aucune norme reconnue à ce sujet et que la syntaxe Mermaid ne l'impose pas.
Les relations entre entités sont représentées par des lignes dont les extrémités portent des marques de cardinalité. Mermaid utilise la notation de patte d'oie, la plus répandue, qui indique visuellement que l'entité à laquelle elle est connectée peut avoir plusieurs instances.
Un diagramme ER peut servir à diverses fins, depuis un modèle logique abstrait ne contenant aucun détail d'implémentation jusqu'à un modèle physique de tables de base de données relationnelle. Inclure des définitions d'attributs dans un diagramme ER aide à comprendre l'usage et la signification des entités ; ces définitions d'attributs ne doivent pas être exhaustives, une petite partie des attributs suffit souvent. Mermaid permet de les définir par leur type et leur nom.
Copier
Intégrer
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
}
Lorsque vous incluez des attributs dans un diagramme ER, vous devez décider si vous incluez les clés étrangères en tant qu'attributs, ce qui peut dépendre du degré auquel vous souhaitez représenter la structure des tables de relation. Si votre diagramme est un modèle logique et ne vise pas à suggérer une implémentation relationnelle, il vaut mieux ne pas inclure ces attributs, car la relation d'association transmet déjà la manière dont les entités sont associées. Par exemple, une structure de données JSON peut implémenter une relation un-à-plusieurs à l'aide d'un tableau, sans attribut de clé étrangère. De même, un langage de programmation orienté objet peut utiliser des pointeurs ou des références vers des collections. Même pour les modèles destinés à une implémentation relationnelle, on peut considérer que l'inclusion d'attributs de clé étrangère répète l'information déjà transmise par la relation et n'ajoute aucune signification à l'entité.
Syntaxe
Entités et relations
La syntaxe Mermaid des diagrammes ER est compatible avec PlantUML et l'étend avec des fonctionnalités permettant d'étiqueter les relations. Chaque instruction comprend les éléments suivants :
Copier
Intégrer
<first-entity> [<relationship> <second-entity> : <relationship-label>]
- first-entity est le nom de la première entité. Le nom prend en charge tout caractère Unicode et peut contenir des espaces s'il est entouré de guillemets doubles.
- relationship décrit la relation mutuelle entre deux entités.
- second-entity est le nom de l'autre entité.
- relationship-label décrit la relation du point de vue de la première entité.
Par exemple :
Copier
Intégrer
PROPERTY ||--|{ ROOM : contains
Cette déclaration peut se comprendre ainsi : une propriété contient une ou plusieurs pièces, et une pièce n'appartient qu'à une seule propriété. Ici, l'étiquette est envisagée du point de vue de la première entité : une propriété contient une pièce, mais une pièce ne contient pas de propriété. Du point de vue de la seconde entité, l'étiquette équivalente est généralement facile à déduire.
Seule la partie first-entity est obligatoire. Cela permet d'afficher des entités sans relation, ce qui est très utile lors de la construction itérative d'un diagramme. Si d'autres parties de l'instruction sont spécifiées, alors toutes les parties sont obligatoires.
Texte Unicode
Les noms d'entités, les relations et les attributs prennent tous en charge le texte unicode.
Copier
Intégrer
erDiagram
"This ❤ Unicode"
Syntaxe des relations
La partie relation de chaque instruction peut être décomposée en trois sous-parties :
- La cardinalité de la première entité par rapport à la seconde entité
- Si la relation confère ou non une identification à l'entité enfant
- La cardinalité de la seconde entité par rapport à la première entité
La cardinalité est une propriété qui décrit le nombre d'éléments d'une autre entité pouvant être associés à l'entité concernée. Dans l'exemple ci-dessus, une PROPERTY peut être associée à une ou plusieurs instances de ROOM, tandis qu'une ROOM ne peut être associée qu'à une seule PROPERTY. Chaque marque de cardinalité comporte deux caractères : le caractère le plus à l'extérieur représente la valeur maximale, et le caractère le plus à l'intérieur représente la valeur minimale. Le tableau ci-dessous résume les possibilités de cardinalité :
| Valeur (gauche) | Valeur (droite) | Signification |
|---|---|---|
| |o | o| | Zéro ou un |
| || | || | Exactement un |
| }o | o{ | Zéro ou plusieurs (sans limite) |
| }| | |{ | Un ou plusieurs (sans limite) |
| Valeur (gauche) | Valeur (droite) | Signification |
|---|---|---|
| one or zero | one or zero | Zéro ou un |
| zero or one | zero or one | Zéro ou un |
| one or more | one or more | Un ou plusieurs |
| one or many | one or many | Un ou plusieurs |
| many(1) | many(1) | Un ou plusieurs |
| 1+ | 1+ | Un ou plusieurs |
| zero or more | zero or more | Zéro ou plusieurs |
| zero or many | zero or many | Zéro ou plusieurs |
| many(0) | many(0) | Zéro ou plusieurs |
| 0+ | 0+ | Zéro ou plusieurs |
| only one | only one | Exactement un |
| 1 | 1 | Exactement un |
Identification
Les relations peuvent être identifiantes ou non identifiantes, et sont respectivement rendues par un trait plein ou un trait en pointillés. Cela est important lorsqu'une entité ne peut pas exister indépendamment sans l'autre. Par exemple, une entreprise qui assure des personnes conduisant des voitures peut avoir besoin de stocker les données de NAMED-DRIVER. Lors de la modélisation, nous pouvons d'abord observer qu'une CAR peut être conduite par de nombreux PERSON, et qu'un PERSON peut conduire de nombreuses CAR ; les deux peuvent exister sans l'autre, il s'agit donc d'une relation non identifiante, que nous pouvons spécifier dans Mermaid comme : PERSON }|..|{ CAR : "driver". Notez les deux points au milieu de la relation, ce qui produira un trait en pointillés entre les deux entités. Toutefois, lorsque cette relation plusieurs-à-plusieurs est décomposée en deux relations un-à-plusieurs, nous observons que NAMED-DRIVER ne pourrait pas exister sans PERSON et CAR. Ces relations deviennent alors des relations identifiantes et sont représentées par un tiret, ce qui correspond à un trait plein :
| Valeur | Alias |
|---|---|
| -- | Identification |
| .. | Non identifiant |
| Valeur | 别名为 |
|---|---|
| to | Identification |
| optionally to | Non identifiant |
Copier
Intégrer
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o..o{ NAMED-DRIVER : is
Copier
Intégrer
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o--o{ NAMED-DRIVER : is
Attributs
Vous pouvez définir des attributs pour une entité en spécifiant le nom de l'entité, suivi d'un bloc contenant plusieurs type name , le bloc étant entouré d'accolades {} . Les attributs sont affichés à l'intérieur du cadre de l'entité, par exemple :
Copier
Intégrer
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
}
La valeur type doit commencer par un caractère alphabétique et peut contenir des chiffres, des tirets, des tirets bas, des parenthèses et des crochets. La valeur name suit un format similaire à celui de type, mais peut également commencer par un astérisque, comme autre option pour indiquer qu'un attribut est une clé primaire. Hormis cela, il n'existe aucune autre restriction ni ensemble implicite de types de données valides.
Alias d'entité
Vous pouvez ajouter un alias à une entité à l'aide de crochets. Si un alias est fourni, le diagramme affichera l'alias au lieu du nom de l'entité ; l'alias suit toutes les mêmes règles que le nom d'entité.
Copier
Intégrer
erDiagram
p[Person] {
string firstName
string lastName
}
a["Customer Account"] {
string email
}
p ||--o| a : has
Clés d'attribut et commentaires
Les attributs peuvent également définir une clé ou un commentaire. La clé peut être une clé primaire (PK), une clé étrangère (FK) ou une clé unique (UK). Pour spécifier plusieurs contraintes de clé sur un même attribut, séparez-les par des virgules (par exemple, PK, FK). Les commentaires sont définis par des guillemets doubles à la fin de l'attribut ; le commentaire ne peut pas contenir de guillemets doubles.
Copier
Intégrer
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
Direction
L'instruction de direction déclare la direction du diagramme.
TB déclare que la direction du diagramme va de haut en bas ; BT peut l'inverser en de bas en haut.
Copier
Intégrer
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 déclare que la direction du diagramme va de gauche à droite ; RL peut l'inverser en de droite à gauche.
Copier
Intégrer
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
}
Définir le style des nœuds
Vous pouvez appliquer un style particulier à un nœud, par exemple une bordure plus épaisse ou une couleur de fond différente.
Copier
Intégrer
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
Vous pouvez également attacher un style à une liste de nœuds dans une même instruction :
Copier
Intégrer
style nodeId1,nodeId2 styleList
Classe
Plutôt que de définir un style à chaque fois, il est plus pratique de définir une classe de style et de l'attacher aux nœuds qui nécessitent une apparence différente.
La définition de classe est illustrée par l'exemple suivant :
Copier
Intégrer
classDef className fill:pink,stroke:#333,stroke-width:4px
Vous pouvez également définir plusieurs classes dans une même instruction :
Copier
Intégrer
classDef firstClassName,secondClassName font-size:12pt
La syntaxe pour attacher une classe à un nœud est la suivante :
Copier
Intégrer
class nodeId1 className
Vous pouvez également attacher une classe à une liste de nœuds dans une même instruction :
Copier
Intégrer
class nodeId1,nodeId2 className
Vous pouvez également attacher plusieurs classes simultanément :
Copier
Intégrer
class nodeId1,nodeId2 className1,className2
Le moyen simple d'ajouter une classe consiste à utiliser l'opérateur ::: pour attacher le nom de classe à un nœud, comme indiqué ci-dessous :
Copier
Intégrer
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
La déclaration d'une relation entre entités peut utiliser la syntaxe suivante :
Copier
Intégrer
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
Comme pour l'instruction class, la syntaxe abrégée permet aussi d'appliquer plusieurs classes à la fois :
Copier
Intégrer
nodeId:::className1,className2
Classe par défaut
Si une classe est nommée default, elle sera attribuée à toutes les classes sans définition de classe particulière.
Copier
Intégrer
classDef default fill:pink,stroke:#333,stroke-width:4px;
Remarque : les styles personnalisés provenant de style ou d'autres instructions de classe sont prioritaires et remplacent le style par défaut. (Par exemple, la classe default définit un fond rose pour un nœud, mais si la classe blue est appliquée, elle donnera une couleur de fond bleue à ce nœud.)
Copier
Intégrer
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
Configuration
Mise en page
La mise en page du diagramme est gérée par render() ; la mise en page par défaut est la mise en page ELK, adaptée aux diagrammes plus grands et plus complexes.
Pour utiliser plutôt la mise en page classique Dagre, vous pouvez la définir dans config du frontmatter YAML
Copier
Intégrer
---
config:
layout: dagre
---
Le contenu du code Mermaid est le suivant :
Copier
Intégrer
---
title: Order example
config:
layout: elk
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses