Mermaid ER Syntax
Last updated: March 2026
Mermaid ER diagrams are a plain-text format for describing entity-relationship schemas. Diagram2Code parses Mermaid erDiagram blocks and converts them to production-ready SQL DDL or ORM model code. This page covers the input syntax accepted by the parser — for output details see SQL DDL Generation and ORM Generation.
erDiagram blocks only. Other Mermaid diagram types (flowchart, sequence, Gantt, etc.) are not parsed and will produce a PARSE_ERROR.Table & Column Syntax
Each entity block defines one database table. The block opens with the table name in UPPER_SNAKE_CASE (converted to lower_snake_case in SQL output), followed by a brace-enclosed list of column definitions.
erDiagram
TABLE_NAME {
type column_name MARKERS "optional comment"
}Each column line contains up to four parts in order:
| Part | Required | Description |
|---|---|---|
| type | Yes | Abstract type (int, string, decimal, boolean, timestamp, uuid, text, json, blob) or a native database type (bigint, varchar(255), varchar2(255), etc.) |
| column_name | Yes | Identifier in snake_case. Column names may not contain spaces. |
| markers | No | One or more of PK (primary key), FK (foreign key), UK (unique constraint). Multiple markers are separated by spaces: PK UK. |
| "comment" | No | A double-quoted string that appears as a column comment in the generated SQL (where supported by the dialect). |
Relationships
Relationships are declared outside entity blocks, one per line. They define the foreign key targets that the generator uses to emit REFERENCES clauses and ORM association annotations.
LEFT_TABLE CARDINALITY "--" CARDINALITY RIGHT_TABLE : "label"
The cardinality tokens use Mermaid's crow's-foot notation. Each side of the -- separator is two characters: the first describes optionality, the second describes multiplicity.
| Token | Meaning |
|---|---|
|| | Exactly one (mandatory, singular) |
|o / o| | Zero or one (optional, singular) |
}| / |{ | One or more (mandatory, many) |
}o / o{ | Zero or more (optional, many) |
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER }|--|{ PRODUCT : contains
USER ||--|| PROFILE : hasCUSTOMER ||--o{ ORDER : places means one Customer places zero-or-more Orders. The generator emits a foreign key from ORDER.customer_id back to CUSTOMER. The relationship label (places) is used for documentation only and does not affect the SQL output.
A many-to-many relationship (}|--|{) causes Diagram2Code to generate a junction table automatically. The junction table is named by joining the two table names in alphabetical order (e.g. order_product) and contains foreign key columns to each parent table.
Common Patterns
One-to-many with explicit FK column
erDiagram
AUTHOR {
int id PK
string name
string email UK
}
POST {
int id PK
int author_id FK
string title
text body
timestamp published_at
}
AUTHOR ||--o{ POST : writesMany-to-many via junction table
Declare the relationship directly — Diagram2Code generates the junction table automatically. You do not need to define it as a separate entity.
erDiagram
STUDENT {
int id PK
string name
string email UK
}
COURSE {
int id PK
string title
string code UK
}
STUDENT }|--|{ COURSE : enrollsSelf-referencing table
A table can reference itself, which is common for hierarchical data such as categories or org charts.
erDiagram
CATEGORY {
int id PK
string name
int parent_id FK "NULL for root categories"
}
CATEGORY ||--o{ CATEGORY : containsFull-featured Example
erDiagram
CATEGORY {
int id PK
string name UK "Category name"
int parent_id FK
}
PRODUCT {
int id PK "Primary key"
string name "Product name"
decimal price
boolean active
string sku UK "Stock keeping unit"
int category_id FK
timestamp created_at
}
CUSTOMER {
int id PK
string email UK
string name
timestamp created_at
}
ORDER {
int id PK
int customer_id FK
decimal total
timestamp placed_at
}
CATEGORY ||--o{ CATEGORY : contains
CATEGORY ||--o{ PRODUCT : groups
CUSTOMER ||--o{ ORDER : places
ORDER }|--|{ PRODUCT : includesKnown Limitations
- Must start with
erDiagram— The keyword must appear exactly as written (case-sensitive) at the beginning of the diagram. Leading blank lines are allowed, but other Mermaid diagram types or content beforeerDiagramcause a parse error. - No spaces in column names — Column identifiers must be valid
snake_casetokens.first_nameis valid;first nameis not. - Comments must be on their own line — Mermaid
%%comments cannot appear on the same line as a column definition or relationship. - No native enum columns — Mermaid has no enum syntax. Use a
stringorvarchar(N)column and add a::CHECKdirective in a comment to generate aCHECKconstraint in the SQL output. - FK columns need a matching relationship line — Marking a column as
FKdoes not automatically infer the target table. You must also add the corresponding relationship line; otherwise the generator cannot emit a validREFERENCESclause.