How to Create ER Diagrams in Confluence (Mermaid erDiagram Examples)
Entity-Relationship (ER) diagrams are the standard way to visualize database schemas. They show the tables in your database, the columns in each table, primary and foreign key constraints, and the relationships between tables -- one-to-one, one-to-many, and many-to-many. Whether you are designing a new database from scratch, documenting an existing schema for onboarding, or collaborating on a data model before writing migration scripts, an ER diagram communicates structure faster than any amount of prose.
If your team uses Confluence for technical documentation, embedding ER diagrams directly on your pages keeps your data model documentation next to your architecture decision records, API specs, and sprint planning notes. With Mermaid Plus for Confluence, you can write ER diagrams in plain text using the erDiagram syntax and render them instantly -- no external drawing tool, no exported PNGs, no stale images.
This guide walks you through the full Mermaid erDiagram syntax, explains every relationship type and key constraint, and provides three copy-paste examples you can drop straight into a Confluence page.
Why Create ER Diagrams in Confluence?
Teams that embed database diagrams inside Confluence instead of linking to external tools see several concrete benefits:
Diagrams stay synchronized with documentation. When your ER diagram lives on the same page as the data dictionary, migration plan, and API contract, all of these artifacts evolve together. Edit the diagram, publish the page, and every stakeholder sees the latest schema.
No stale images. Exporting a PNG from a database design tool and attaching it to Confluence guarantees that the image drifts out of date the next time someone runs a migration. A Mermaid macro always renders the current code. If someone changes the schema, they change the Mermaid source on the page.
Text-based and searchable. Mermaid ER diagrams are plain text, which means they integrate with Confluence page history, diffs, and full-text search. You can find every page that references the orders table by searching Confluence -- even if the table name only appears inside a Mermaid macro.
Fast to create and iterate. Typing CUSTOMER ||--o{ ORDER : places is faster than dragging table shapes, drawing relationship lines, and adjusting layout in a visual editor. When you want to add a column, you type it. When you want to change a cardinality, you change one character.
Step-by-Step Tutorial: Create Your First ER Diagram
Follow these five steps to go from a blank Confluence page to a fully rendered database schema diagram.
Step 1 -- Install Mermaid Plus for Confluence
Head to the Atlassian Marketplace and search for Mermaid Plus for Confluence. Click Get App and follow the installation prompts. The app supports both Confluence Cloud and Confluence Data Center. If your organization requires admin approval for marketplace apps, send the link to your Confluence administrator.
Once installed, the Mermaid Plus macro becomes available on every space in your Confluence instance. No per-space configuration required.
Step 2 -- Insert the Mermaid Macro on a Confluence Page
Open any Confluence page in edit mode. Type /mermaid in the editor and select Mermaid Plus for Confluence from the dropdown. The configuration panel opens with a three-column layout:
- Left column: Live Preview, which renders your diagram in real time as you type
- Middle column: Quick Templates for all 26 supported diagram types, including ER diagrams
- Right column: Settings (font, colors, theme, output size) and the Code Editor
You can also click the ER Diagram template in the Quick Templates column to load a starter example into the editor.
Step 3 -- Write the erDiagram Header and Define Entities
Start your ER diagram with the erDiagram keyword. Then define entities and their attributes. Each attribute can have a key type and a comment:
erDiagram
CUSTOMER {
int id PK
string email UK
string name
date created_at
}
The key types are PK (primary key), FK (foreign key), and UK (unique key). You will learn more about key types later in this guide.
Step 4 -- Add Relationships Between Entities
Mermaid supports the full set of ER cardinality operators. To connect two entities, use a relationship line between them:
erDiagram
CUSTOMER ||--o{ ORDER : places
The ||--o{ operator creates a one-to-many relationship: one customer places zero or more orders. You will find a complete reference table for all cardinality operators in the next section.
Step 5 -- Save and Publish the Diagram
Check the live preview in the left column to verify the diagram renders correctly. Adjust the theme, colors, or output size in the right column if needed. When you are satisfied, click Save to insert the macro into the page, then Publish the Confluence page.
To edit the diagram later, click on the rendered diagram in view mode and select Edit. All your code and settings are preserved.
For a complete walkthrough of the configuration panel, themes, font families, color customization, and all 26 supported diagram types, see the Mermaid Plus for Confluence usage guide.
Mermaid ER Diagram Syntax Reference
Before diving into the full examples, here is a quick-reference for the syntax elements you will use most often.
Entity Definitions
An entity represents a table in your database. Define an entity by writing its name in uppercase (by convention) followed by a block of attributes in curly braces:
erDiagram
PRODUCT {
int id PK
string name
string description
decimal price
int stock_quantity
int category_id FK
}
Each attribute line follows this format:
type name [key_type] ["comment"]
- type: The data type (e.g.,
int,string,decimal,date,boolean,uuid,text,timestamp) - name: The column name
- key_type (optional):
PKfor primary key,FKfor foreign key,UKfor unique key - comment (optional): A quoted description of the column
Key Types
Key types mark special constraints on columns. Mermaid renders them with distinct visual indicators:
| Key Type | Syntax | Description |
|---|---|---|
| Primary Key | int id PK | Uniquely identifies each row. Only one per entity. |
| Foreign Key | int user_id FK | References a primary key in another entity. |
| Unique Key | string email UK | Enforces uniqueness but is not the primary identifier. |
You can combine key types on the same column in some database designs, but Mermaid assigns one visual indicator per attribute line. For composite keys, mark each participating column separately.
Example with all three key types:
erDiagram
USER {
int id PK
string email UK
string username UK
string password_hash
int organization_id FK
timestamp created_at
}
Relationship Cardinality
Relationships are the core of any ER diagram. Mermaid uses a specific notation to express cardinality between two entities. The syntax consists of three parts: the left cardinality, the relationship line, and the right cardinality.
Cardinality Symbols
| Symbol | Meaning |
|---|---|
| ` | |
| ` | o` |
| `} | ` |
o{ | Zero or more (optional, may be none) |
Common Relationship Patterns
| Relationship | Syntax | Meaning |
|---|---|---|
| One-to-one (mandatory) | ||--|| | Each A has exactly one B, and each B has exactly one A |
| One-to-one (optional) | ||--o| | Each A has zero or one B |
| One-to-many | ||--o{ | One A has zero or more B's |
| One-to-many (mandatory) | ||--|{ | One A has one or more B's |
| Many-to-one | }o--|| | Many A's relate to one B |
| Many-to-many | }o--o{ | Many A's relate to many B's |
You can add a label to any relationship by appending a colon and text after the second entity:
CUSTOMER ||--o{ ORDER : places
PRODUCT ||--o{ ORDER_ITEM : "included in"
Full Cardinality Reference
Here is every possible combination. The first character pair describes the left entity's cardinality, and the last pair describes the right entity's cardinality:
| Left | Line | Right | Example |
|---|---|---|---|
|| | -- | || | One to one (both mandatory) |
|| | -- | o| | One to zero-or-one |
|| | -- | |{ | One to one-or-many |
|| | -- | o{ | One to zero-or-many |
o| | -- | || | Zero-or-one to one |
o| | -- | o| | Zero-or-one to zero-or-one |
o| | -- | |{ | Zero-or-one to one-or-many |
o| | -- | o{ | Zero-or-one to zero-or-many |
|{ | -- | || | One-or-many to one |
|{ | -- | o| | One-or-many to zero-or-one |
|{ | -- | |{ | One-or-many to one-or-many |
|{ | -- | o{ | One-or-many to zero-or-many |
o{ | -- | || | Zero-or-many to one |
o{ | -- | o| | Zero-or-many to zero-or-one |
o{ | -- | |{ | Zero-or-many to one-or-many |
o{ | -- | o{ | Zero-or-many to zero-or-many |
In practice, you will use ||--o{ (one-to-many) and ||--|| (one-to-one) most frequently. Many-to-many relationships (}o--o{) are typically resolved into a junction table in a normalized database schema.
Attribute Data Types
Mermaid supports a wide range of data types for ER diagram attributes. While these are not enforced by the diagram itself, they serve as documentation for your team:
| Type | Usage |
|---|---|
int | Integer numbers |
bigint | Large integers |
float | Floating-point numbers |
decimal | Fixed-precision numbers (prices, amounts) |
boolean | True/false values |
string | Short text (VARCHAR) |
text | Long text (TEXT, CLOB) |
date | Date without time |
timestamp | Date and time |
uuid | Universally unique identifier |
json | JSON data |
blob | Binary data |
Entity Name Conventions
Mermaid ER diagrams use uppercase entity names by convention (e.g., CUSTOMER, ORDER, LINE_ITEM). This distinguishes entities from attributes and relationship labels. Use underscores for multi-word entity names since Mermaid does not support spaces in entity names:
LINE_ITEM
ORDER_STATUS
USER_SESSION
Relationship labels use lowercase with spaces, written after a colon:
CUSTOMER ||--o{ ORDER : places
3 Copy-Paste ER Diagram Examples
Below are three practical examples you can paste directly into the Mermaid Plus macro in Confluence. Each example demonstrates progressively more advanced Mermaid ER diagram features.
Example 1 -- Basic ER Diagram: Library Management System
This example shows a simple library system with books, authors, members, and loans. It covers all three relationship types: one-to-one, one-to-many, and many-to-many. This is a good starting point for documenting any straightforward database schema.
erDiagram
AUTHOR {
int id PK
string name
string nationality
date birth_date
}
BOOK {
int id PK
string title
string isbn UK
int publication_year
int author_id FK
int genre_id FK
}
GENRE {
int id PK
string name UK
string description
}
MEMBER {
int id PK
string email UK
string first_name
string last_name
string phone
date membership_date
}
LOAN {
int id PK
int book_id FK
int member_id FK
date checkout_date
date due_date
date return_date
}
AUTHOR ||--o{ BOOK : writes
GENRE ||--o{ BOOK : categorizes
MEMBER ||--o{ LOAN : borrows
BOOK ||--o{ LOAN : "is borrowed"
This diagram covers three key concepts:
- One-to-many relationships -- Each author writes zero or more books (
AUTHOR ||--o{ BOOK), each genre categorizes zero or more books, and each member has zero or more loans - Primary and foreign keys -- Every entity has a
PKcolumn, and relationship tables likeLOANhaveFKcolumns referencingBOOKandMEMBER - Unique constraints --
isbnonBOOKandemailonMEMBERare markedUKto indicate uniqueness
Example 2 -- E-Commerce Database Schema
This example models a realistic e-commerce database with customers, products, orders, payments, and shipping. It demonstrates how to handle many-to-many relationships through junction tables, composite foreign keys, and a variety of cardinality patterns. This is the kind of diagram you would include in a technical design document or database migration plan.
erDiagram
CUSTOMER {
int id PK
string email UK
string password_hash
string first_name
string last_name
string phone
timestamp created_at
}
ADDRESS {
int id PK
int customer_id FK
string street_line_1
string street_line_2
string city
string state
string postal_code
string country
boolean is_default
}
PRODUCT {
int id PK
string name
string description
decimal price
int stock_quantity
string sku UK
int category_id FK
timestamp created_at
timestamp updated_at
}
CATEGORY {
int id PK
string name UK
string slug UK
int parent_category_id FK
string description
}
PRODUCT_TAG {
int id PK
string name UK
}
PRODUCT_TAG_MAP {
int product_id FK
int tag_id FK
}
ORDER {
int id PK
int customer_id FK
string status
decimal subtotal
decimal tax_amount
decimal shipping_cost
decimal total_amount
string shipping_address_snapshot
timestamp created_at
timestamp updated_at
}
ORDER_ITEM {
int id PK
int order_id FK
int product_id FK
int quantity
decimal unit_price
decimal line_total
}
PAYMENT {
int id PK
int order_id FK
string payment_method
string transaction_id UK
decimal amount
string status
timestamp paid_at
}
SHIPMENT {
int id PK
int order_id FK
string carrier
string tracking_number UK
string status
timestamp shipped_at
timestamp estimated_delivery
timestamp delivered_at
}
REVIEW {
int id PK
int product_id FK
int customer_id FK
int rating
string title
string body
timestamp created_at
}
WISHLIST {
int id PK
int customer_id FK
int product_id FK
timestamp added_at
}
CUSTOMER ||--o{ ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ REVIEW : writes
CUSTOMER ||--o{ WISHLIST : "adds to"
CATEGORY ||--o{ CATEGORY : "sub-category of"
CATEGORY ||--o{ PRODUCT : contains
PRODUCT ||--o{ ORDER_ITEM : "included in"
PRODUCT ||--o{ REVIEW : "receives"
PRODUCT ||--o{ PRODUCT_TAG_MAP : tagged
PRODUCT_TAG ||--o{ PRODUCT_TAG_MAP : applied
ORDER ||--|{ ORDER_ITEM : contains
ORDER ||--o| PAYMENT : "paid by"
ORDER ||--o| SHIPMENT : "shipped via"
This diagram introduces several advanced features:
- Self-referencing relationship --
CATEGORY ||--o{ CATEGORYmodels a hierarchical category tree where a category can have sub-categories - Many-to-many via junction table --
PRODUCT_TAG_MAPresolves the many-to-many relationship betweenPRODUCTandPRODUCT_TAG - Mandatory one-to-many --
ORDER ||--|{ ORDER_ITEMuses|{to indicate that every order must have at least one item - Optional one-to-one --
ORDER ||--o| PAYMENTuseso|to indicate that an order may or may not have a payment record (e.g., pending orders) - Unique constraints on transactional data --
transaction_idonPAYMENTandtracking_numberonSHIPMENTare markedUK - Snapshot fields --
shipping_address_snapshotonORDERdemonstrates denormalization for audit purposes
Example 3 -- SaaS Multi-Tenant Database Schema
This example models a multi-tenant SaaS application with organizations, users, roles, permissions, projects, and audit logs. It is the most complex of the three examples and demonstrates how to model row-level security patterns, polymorphic associations, and tenant isolation in a database schema. Use this diagram as a starting point when designing any B2B SaaS data model.
erDiagram
ORGANIZATION {
int id PK
string name
string slug UK
string plan
int max_users
boolean is_active
timestamp trial_ends_at
timestamp created_at
}
USER {
int id PK
int organization_id FK
string email UK
string password_hash
string first_name
string last_name
string avatar_url
boolean is_active
timestamp last_login_at
timestamp created_at
}
ROLE {
int id PK
int organization_id FK
string name
string description
boolean is_system
}
PERMISSION {
int id PK
string name UK
string resource
string action
string description
}
USER_ROLE {
int user_id FK
int role_id FK
timestamp assigned_at
}
ROLE_PERMISSION {
int role_id FK
int permission_id FK
}
PROJECT {
int id PK
int organization_id FK
string name
string key UK
string description
string status
int owner_id FK
timestamp created_at
timestamp updated_at
}
PROJECT_MEMBER {
int id PK
int project_id FK
int user_id FK
string role
timestamp joined_at
}
TASK {
int id PK
int project_id FK
int assignee_id FK
int reporter_id FK
string title
string description
string status
string priority
string task_type
int parent_task_id FK
timestamp due_date
timestamp created_at
timestamp updated_at
}
TASK_COMMENT {
int id PK
int task_id FK
int author_id FK
text body
timestamp created_at
timestamp updated_at
}
TASK_ATTACHMENT {
int id PK
int task_id FK
int uploaded_by FK
string file_name
string file_url
int file_size
string mime_type
timestamp uploaded_at
}
AUDIT_LOG {
int id PK
int organization_id FK
int actor_id FK
string action
string resource_type
int resource_id
json changes
string ip_address
timestamp performed_at
}
API_KEY {
int id PK
int organization_id FK
int created_by FK
string name
string key_hash UK
string prefix
string[] scopes
timestamp expires_at
timestamp created_at
}
ORGANIZATION ||--|{ USER : employs
ORGANIZATION ||--o{ ROLE : defines
ORGANIZATION ||--o{ PROJECT : owns
ORGANIZATION ||--o{ AUDIT_LOG : "logs for"
ORGANIZATION ||--o{ API_KEY : "issues"
USER ||--o{ USER_ROLE : has
ROLE ||--o{ USER_ROLE : assigned
ROLE ||--o{ ROLE_PERMISSION : grants
PERMISSION ||--o{ ROLE_PERMISSION : "included in"
PROJECT ||--o{ PROJECT_MEMBER : "has members"
USER ||--o{ PROJECT_MEMBER : "joins"
PROJECT ||--|{ TASK : contains
USER ||--o{ TASK : assigned
USER ||--o{ TASK : reported
TASK ||--o{ TASK : "sub-task of"
TASK ||--o{ TASK_COMMENT : has
TASK ||--o{ TASK_ATTACHMENT : has
USER ||--o{ TASK_COMMENT : authors
USER ||--o{ TASK_ATTACHMENT : uploads
USER ||--o{ AUDIT_LOG : performs
USER ||--o{ API_KEY : creates
This diagram demonstrates every major Mermaid ER diagram feature in a production-ready context:
- Multi-tenant isolation -- Every top-level entity has an
organization_id FKcolumn, enforcing tenant boundaries at the data layer - Role-based access control (RBAC) -- The
USER_ROLE,ROLE,ROLE_PERMISSION, andPERMISSIONentities form a complete RBAC model with many-to-many relationships resolved through junction tables - Self-referencing hierarchy --
TASK ||--o{ TASKallows tasks to have sub-tasks, modeling an unlimited nesting depth - Multiple foreign keys to the same table --
TASKhas bothassignee_id FKandreporter_id FKpointing toUSER, with corresponding relationship lines - Polymorphic audit trail --
AUDIT_LOGusesresource_typeandresource_idto track changes across any entity type, with ajsoncolumn for change details - API key management --
API_KEYstores hashed keys with scope arrays and expiration, scoped to organizations - Mandatory vs optional cardinality --
ORGANIZATION ||--|{ USER(every org has at least one user) vsORGANIZATION ||--o{ API_KEY(API keys are optional)
Tips for Building Effective ER Diagrams
Normalize Before Diagramming
Before writing a single line of Mermaid, make sure your schema follows at least third normal form (3NF). Each entity should represent one concept, each attribute should depend on the whole primary key, and there should be no transitive dependencies. ER diagrams are most useful when the underlying model is clean.
Start with Entities, Then Add Relationships
Begin by listing all your entities and their attributes. Get the column names and key types right first. Then add relationship lines between entities. This two-pass approach prevents you from getting lost in cardinality notation before the entities themselves are well-defined.
Use Junction Tables for Many-to-Many
Many-to-many relationships (}o--o{) are valid in Mermaid syntax, but in a relational database you always resolve them through a junction table. Instead of drawing a direct many-to-many line, create an intermediate entity with two foreign keys:
-- Instead of this:
PRODUCT }o--o{ TAG : "tagged with"
-- Do this:
PRODUCT ||--o{ PRODUCT_TAG_MAP : tagged
TAG ||--o{ PRODUCT_TAG_MAP : applied
This matches how the database actually implements the relationship and makes the diagram more useful as a reference for writing SQL.
Label Every Relationship
Add descriptive labels to your relationship lines. CUSTOMER ||--o{ ORDER : places is clearer than CUSTOMER ||--o{ ORDER. The label tells the reader what the relationship means in business terms, not just that a foreign key exists.
Keep Diagrams Focused
A single ER diagram does not need to show every table in your database. Focus on one subsystem or one feature area per diagram. If you find yourself adding more than 12-15 entities, consider splitting the diagram into multiple pages and linking between them. Two focused diagrams are always better than one overwhelming diagram.
Be Consistent with Naming Conventions
Pick a naming convention and stick to it throughout the diagram. Common conventions include:
- Entity names: UPPER_SNAKE_CASE (e.g.,
ORDER_ITEM,USER_SESSION) - Attribute names: snake_case (e.g.,
created_at,user_id) - Primary keys: Always named
idor{entity_name}_id - Foreign keys: Always named
{referenced_entity}_id(e.g.,customer_id,order_id)
Consistent naming makes the diagram self-documenting and reduces the cognitive load on readers.
Use Themes for Visual Consistency
Mermaid Plus for Confluence offers four built-in themes: Default, Dark, Forest, and Neutral. Pick one theme for all ER diagrams in a space and stick with it. The Default theme lets you customize node, text, border, line, and background colors to match your company brand. Consistent visual style across pages makes your documentation feel polished and professional.
For detailed configuration options including font families, color pickers, and output sizes, refer to the Mermaid Plus for Confluence usage guide.
Common Mistakes and How to Fix Them
Missing erDiagram header. Every ER diagram must start with the erDiagram keyword on its own line. Writing entity definitions without this header produces a parse error. The correct form is:
erDiagram
CUSTOMER ||--o{ ORDER : places
Wrong cardinality direction. The cardinality symbols closest to an entity describe that entity's role. In CUSTOMER ||--o{ ORDER : places, the || is next to CUSTOMER (exactly one customer) and o{ is next to ORDER (zero or more orders). If your diagram looks reversed, swap the sides of the relationship line.
Spaces in entity names. Mermaid does not support spaces in entity names. Use underscores instead: ORDER_ITEM, not ORDER ITEM. Relationship labels can contain spaces because they are written after the colon.
Missing foreign key annotations. If a column references another table's primary key, mark it with FK. This makes the relationship visually explicit in the diagram and helps readers trace referential integrity without hunting through relationship lines.
Overcrowding. An ER diagram with 20 entities and 40 relationships becomes unreadable. If your diagram has grown too large, split it by domain, subsystem, or feature area. Link the pages together so readers can navigate between focused views.
Forgetting to close attribute blocks. Every { must have a matching }. If your diagram fails to render, check that every entity's attribute block is properly closed. The live preview in Mermaid Plus will show you parse errors in real time, which makes this easy to catch.
ER Diagrams vs Class Diagrams vs Flowcharts
ER diagrams are not the right tool for every situation. Here is a quick guide to help you choose the right diagram type:
- ER diagram -- Use when documenting relational database schemas, data models, and table relationships. ER diagrams focus on tables, columns, key constraints, and cardinality.
- Class diagram -- Use when documenting object-oriented systems, domain models, and API contracts with methods, visibility, and inheritance. See how to create class diagrams in Confluence.
- Flowchart -- Use when documenting processes, decision trees, approval workflows, and algorithmic logic. See how to create flowcharts in Confluence.
Many technical design documents benefit from combining multiple diagram types on the same Confluence page. An ER diagram shows the data model, a class diagram shows the application layer, and a flowchart shows the business process that ties them together.
Mermaid Syntax Cheat Sheet
For a quick reference covering ER diagrams and all other Mermaid diagram types supported in Confluence, bookmark the Mermaid syntax cheat sheet for Confluence. It covers flowcharts, sequence diagrams, class diagrams, ER diagrams, Gantt charts, and more in a single-page reference.
Related Resources
- Mermaid Plus for Confluence usage guide -- configuration panel walkthrough, theme settings, font and color customization, and all 26 supported diagram types
- How to create class diagrams in Confluence -- document object-oriented systems with inheritance, composition, and generics using copy-paste Mermaid examples
- Mermaid syntax cheat sheet for Confluence -- quick reference for flowcharts, sequence diagrams, ER diagrams, Gantt charts, and more
- How to create flowcharts in Confluence -- process diagrams, decision trees, and workflow documentation with Mermaid
ER diagrams are one of the most valuable tools in a software team's documentation toolkit. They capture the data model of your system in a way that prose alone cannot match. With Mermaid Plus for Confluence, creating and maintaining ER diagrams is as simple as writing text. Install the app, paste one of the examples above into a Confluence page, and start documenting your database schema where it belongs -- alongside everything else your team needs.