ER diagram
An entity-relationship diagram (ER diagram for short) describes interrelated things of interest in a specific domain of knowledge. A basic ER diagram is composed of entity types (which classify the things of interest) and specifies the relationships that can exist between entities (instances of those entity types),Note that in the practical use of ER diagrams, 'entity type' is almost always simply referred to as 'entity'. For example, the 'CUSTOMER entity type' is usually referred to directly as the 'CUSTOMER entity'. This practice is so common that other ways are not recommended, but technically an entity is an abstract instance of an entity type, and an ER diagram displays exactly these abstract instances and the relationships between them. This is why entities are always named using singular nouns.
Copy
Embed
---
title: Order example
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
Entity names are usually uppercase, although there is no accepted standard for this and the Mermaid syntax does not require it.
The relationships between entities are represented by lines with endpoint markers that indicate cardinality. Mermaid uses the most popular crow's foot notation; the crow's foot intuitively indicates that the entity it connects to may have multiple instances.
ER diagrams can be used for a variety of purposes, from an abstract logical model that contains no implementation details to a physical model of relational database tables. Including attribute definitions on an ER diagram helps in understanding the purpose and meaning of an entity; these attribute definitions do not need to be exhaustive, and usually a small subset of attributes is sufficient. Mermaid allows them to be defined by their type and name.
Copy
Embed
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
}
When including attributes on an ER diagram, you must decide whether to include foreign keys as attributes; this may depend on how much you want to represent the relational table structure. If your diagram is a logical model and is not intended to imply a relational implementation, it is best not to include these attributes, because the relationships already convey how the entities are associated. For example, a JSON data structure can implement a one-to-many relationship using an array without a foreign key attribute. Similarly, object-oriented programming languages can use pointers or references to collections. Even for models intended for a relational implementation, it may be considered that including foreign key attributes duplicates the information conveyed by the relationships and does not add meaning to the entity.
Syntax
Entities and relationships
The Mermaid syntax for ER diagrams is compatible with PlantUML and extends the functionality for labeling relationships. Each statement includes the following:
Copy
Embed
<first-entity> [<relationship> <second-entity> : <relationship-label>]
- first-entity is the name of the first entity. The name supports any Unicode character and, if enclosed in double quotes, can contain spaces.
- relationship describes the mutual relationship between the two entities.
- second-entity is the name of the other entity.
- relationship-label describes the relationship from the perspective of the first entity.
For example:
Copy
Embed
PROPERTY ||--|{ ROOM : contains
This declaration can be understood as: a property contains one or more rooms, while a room belongs to only one property. The label here is from the perspective of the first entity: a property contains a room, but a room does not contain a property. From the perspective of the second entity, the equivalent label can usually be inferred easily.
Only the first-entity part is mandatory. This makes it possible to display entities without relationships, which is very useful when building a diagram iteratively. If other parts of the statement are specified, then all parts are required.
Unicode text
Entity names, relationships, and attributes all support unicode text.
Copy
Embed
erDiagram
"This ❤ Unicode"
Relationship syntax
The relationship part of each statement can be split into three sub-parts:
- The cardinality of the first entity relative to the second entity
- Whether the relationship gives the child entity its identity
- The cardinality of the second entity relative to the first entity
Cardinality is a property that describes the number of elements of another entity that can be associated with the entity involved. In the example above, one PROPERTY can be associated with one or more ROOM instances, while one ROOM can be associated with only one PROPERTY. Each cardinality marker has two characters; the outermost character represents the maximum and the innermost character represents the minimum. The table below summarizes the possible cardinalities:
| Value (left) | Value (right) | Meaning |
|---|---|---|
| |o | o| | Zero or one |
| || | || | Exactly one |
| }o | o{ | Zero or more (no upper limit) |
| }| | |{ | One or more (no upper limit) |
| Value (left) | Value (right) | Meaning |
|---|---|---|
| one or zero | one or zero | Zero or one |
| zero or one | zero or one | Zero or one |
| one or more | one or more | One or more |
| one or many | one or many | One or more |
| many(1) | many(1) | One or more |
| 1+ | 1+ | One or more |
| zero or more | zero or more | Zero or more |
| zero or many | zero or many | Zero or more |
| many(0) | many(0) | Zero or more |
| 0+ | 0+ | Zero or more |
| only one | only one | Exactly one |
| 1 | 1 | Exactly one |
Identifying
Relationships can be identifying or non-identifying, rendered with a solid line or a dashed line respectively. This is important when one of the entities cannot exist independently without the other. For example, a company providing insurance for people driving cars may need to store data about NAMED-DRIVER. When modeling, we might first observe that a CAR can be driven by many PERSONs, and a PERSON can drive many CARs; both can exist without the other, so this is a non-identifying relationship, which we can specify in Mermaid as: PERSON }|..|{ CAR : "driver". Note the two dots in the middle of the relationship, which cause a dashed line to be drawn between the two entities. However, when this many-to-many relationship is resolved into two one-to-many relationships, we observe that NAMED-DRIVER cannot exist without PERSON and CAR. These relationships become identifying relationships and are represented with a hyphen, corresponding to a solid line:
| Value | Alias |
|---|---|
| -- | Identifying |
| .. | Non-identifying |
| Value | 别名为 |
|---|---|
| to | Identifying |
| optionally to | Non-identifying |
Copy
Embed
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o..o{ NAMED-DRIVER : is
Copy
Embed
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
PERSON }o--o{ NAMED-DRIVER : is
Attributes
Attributes can be defined for an entity by specifying the entity name, followed by a block containing several type name entries, where the block is enclosed in braces {}. The attributes are displayed inside the entity box, for example:
Copy
Embed
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
}
The type value must begin with an alphabetic character and can contain digits, hyphens, underscores, parentheses, and square brackets. The name value follows a similar format to type, but can also begin with an asterisk as another option to indicate that the attribute is a primary key. Beyond this, there are no other restrictions, and there is no implied set of valid data types.
Entity aliases
An alias can be added to an entity using square brackets. If an alias is provided, the alias is displayed in the diagram instead of the entity name, and the alias follows all the same rules as entity names.
Copy
Embed
erDiagram
p[Person] {
string firstName
string lastName
}
a["Customer Account"] {
string email
}
p ||--o| a : has
Attribute keys and comments
Attributes can also define keys or comments. A key can be a primary key (PK), a foreign key (FK), or a unique key (UK). To specify multiple key constraints on a single attribute, separate them with commas (for example, PK, FK). Comments are defined by double quotes at the end of the attribute, and the comment cannot contain double quote characters.
Copy
Embed
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
A direction statement declares the direction of the diagram.
TB declares the direction of the diagram as top to bottom, and BT can reverse it to bottom to top.
Copy
Embed
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 declares the direction of the diagram as left to right, and RL can reverse it to right to left.
Copy
Embed
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
}
Setting node styles
Specific styles can be applied to nodes, such as a thicker border or a different background color.
Copy
Embed
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
Styles can also be attached to a list of nodes in a single statement:
Copy
Embed
style nodeId1,nodeId2 styleList
Class
More convenient than defining styles each time is to define a style class and attach that class to the nodes that need a different appearance.
A class is defined as shown in the following example:
Copy
Embed
classDef className fill:pink,stroke:#333,stroke-width:4px
Multiple classes can also be defined in a single statement:
Copy
Embed
classDef firstClassName,secondClassName font-size:12pt
The syntax for attaching a class to a node is as follows:
Copy
Embed
class nodeId1 className
You can also attach a class to a list of nodes in a single statement:
Copy
Embed
class nodeId1,nodeId2 className
You can also attach multiple classes at the same time:
Copy
Embed
class nodeId1,nodeId2 className1,className2
A convenient way to add a class is to use the operator ::: to attach a class name to a node, as shown below:
Copy
Embed
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
The following syntax can be used to declare relationships between entities:
Copy
Embed
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
Similar to the class statement, the shorthand syntax can also apply multiple classes at once:
Copy
Embed
nodeId:::className1,className2
Default class
If a class is named default, it will be assigned to all classes that do not have a specific class definition.
Copy
Embed
classDef default fill:pink,stroke:#333,stroke-width:4px;
Note: custom styles from style or other class statements take precedence and override the default style. (For example, the default class sets a pink background for nodes, but if the blue class is applied, it will give that node a blue background color.)
Copy
Embed
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
Layout
The layout of the diagram is handled by render(); the default layout is the ELK layout, which is suitable for larger and more complex diagrams.
To use the classic Dagre layout instead, you can set it in the config of the YAML frontmatter
Copy
Embed
---
config:
layout: dagre
---
The Mermaid code content is as follows:
Copy
Embed
---
title: Order example
config:
layout: elk
---
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses