Data Modeling with Mermaid: Entity Relationship Diagrams (ERD)
Michael Chang
DBA
A robust database schema is the backbone of any application. Traditionally, Entity Relationship Diagrams (ERDs) were created in tools like MySQL Workbench or dbdiagram.io. While these tools are powerful, they disconnect the design from the codebase. Mermaid allows you to define your schema in Markdown, making it perfect for including in your `README.md` or design documents.
Understanding Cardinality and Crow's Foot Notation
The most critical part of an ERD is defining how entities relate to one another. Mermaid uses a concise syntax to represent standard Crow's Foot notation:
- `||--||` : One-to-One (Rare, often implies same table)
- `||--|{` : One-to-Many (Standard parent-child)
- `||--o{` : One-to-Many (Optional, child can exist without parent or parent has zero children)
- `}o--o{` : Many-to-Many (Requires a join table in SQL)
When designing a schema, you define the entity name, followed by a block `{}` containing the attributes. You can also specify the data type and constraints (PK, FK, UK).
Full-Scale SaaS Schema Example
Let's design a comprehensive schema for a SaaS platform that includes Organizations, Users, Roles, Projects, and Tasks. We will also include a join table for the Many-to-Many relationship between Users and Projects.
Note: Look at `PROJECT_ASSIGNMENT`. This is a classic 'Join Table' or 'Associative Entity'. In Mermaid, we model this explicitly because physically, in the database, it is a table. Note that it has a Composite Primary Key (PK) made up of two Foreign Keys (FK).
Non-Identifying vs Identifying Relationships
Mermaid supports distinguishing between identifying and non-identifying relationships using solid (`--`) vs dashed (`..`) lines. An identifying relationship means the child cannot be uniquely identified without the parent (e.g., a Line Item on an Invoice).
erDiagram
INVOICE ||--|{ INVOICE_ITEM : contains
INVOICE {
int id PK
}
INVOICE_ITEM {
int invoice_id PK, FK
int item_index PK
}In the snippet above, `INVOICE_ITEM` is weak; it doesn't make sense to have an item #1 without knowing which invoice it belongs to. This nuance is vital for DBAs designing clustered indexes.
Indexing & Performance Considerations
Once the logical model is set, translate it to physical concerns: clustered vs non-clustered indexes, partitioning keys, and query patterns. Mermaid ERDs can include notes on expected read/write ratios so DBAs choose the right indexing strategy from day one.
- Mark high-cardinality columns as potential partition keys (e.g., tenant_id, date).
- Call out heavy joins so you can validate composite indexes early.
- Highlight soft-delete or archival flows to separate hot vs cold data.
Note: Keep ERDs versioned with migrations. Each migration PR should update the Mermaid ERD so schema drift is detectable during review.