Mermaid code
erDiagram
CUSTOMER ||--o{ ADDRESS : has
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ ORDER_ITEM : contains
ORDER ||--o| PAYMENT : "paid by"
PRODUCT ||--o{ ORDER_ITEM : "appears in"
CATEGORY ||--o{ PRODUCT : groups
CUSTOMER {
int id PK
string email UK
}
ORDER {
int id PK
int customer_id FK
string status
decimal total
}
ORDER_ITEM {
int id PK
int order_id FK
int product_id FK
int quantity
decimal unit_price
} Paste this into any tool that renders Mermaid, or into the editor to change the theme and export PNG or SVG. Syntax reference: Entity Relationship guide.
What this diagram shows
The relationship lines at the top carry the rules. CUSTOMER ||--o{ ORDER reads as one customer places zero or more orders. ORDER ||--|{ ORDER_ITEM requires at least one item per order. ORDER ||--o| PAYMENT allows an unpaid order with at most one payment. ORDER_ITEM stores unit_price so a later price change on PRODUCT does not rewrite history. ADDRESS, CATEGORY, PRODUCT, and PAYMENT are declared through relationships only, which keeps the diagram focused on the order path; add attribute blocks for them as your schema settles.
How to adapt it
- Change
ORDER ||--o| PAYMENTtoORDER ||--o{ PAYMENTif you support split or retried payments. - Add a
PRODUCT_CATEGORYjoin entity and makeCATEGORY }o--o{ PRODUCTif products belong to several categories. - Add an
ADDRESSattribute block withint customer_id FKandstring typeto distinguish billing from shipping addresses. - Rename
string statusto an explicit list in a comment, for example%% status: pending, paid, shipped, cancelled, so the allowed values travel with the diagram. - Add
INVENTORYwithint product_id FKandint on_handif stock is tracked per warehouse.
FAQ
Why does ORDER_ITEM repeat the price when PRODUCT already has one?
Because the product price changes and past orders must not. Copying unit_price into the line item at checkout is the standard fix. The diagram makes that decision visible by giving both entities a price attribute.
What does the crow's foot notation mean in Mermaid?
Each side of the connector has two characters. || is exactly one, o| is zero or one, }| is one or more, and o{ is zero or more. The left pair describes the left entity's side, the right pair the right entity's side.
Can I show indexes or unique constraints?
Mermaid supports PK, FK, and UK as attribute key markers. Use string email UK to mark a unique column. Indexes that are not constraints have no syntax; put them in a comment line starting with %%.