Entity-relationship diagrams

Under the erd header, blocks declare entities and their fields, and statements between them declare relations. The connector is the cardinality, drawn in crow's-foot notation.

erd
title: Blog schema

users [blue] {
  id uuid pk
  email string
  team_id uuid fk
}
teams {
  id uuid pk
  name string
}
posts {
  id uuid pk
  author_id uuid fk
  title string
}

users N:1 teams: belongs to
users 1:N posts: writes
Blog schemausersid (pk)uuidemailstringteam_id (fk)uuidteamsid (pk)uuidnamestringpostsid (pk)uuidauthor_id (fk)uuidtitlestringbelongs towrites

Entities and fields#

  • Entity: Name [color] { fields }, or id = Name { … } for an explicit id. The opening { and closing } sit on their own lines, with one field per line between them.
  • Field: name type key. The type and key are optional; a key is pk or fk. Field names with spaces use quotes.
  • An empty entity (posts { }) is fine; its fields can be filled in later, or it can stand as a bare table.
erd
customers {
  id uuid pk
  "full name" string
  email string
}
orders {
  id uuid pk
  customer_id uuid fk
  total decimal
  placed_at timestamp
}
customers 1:N orders: places
Diagramcustomersid (pk)uuidfull namestringemailstringordersid (pk)uuidcustomer_id (fk)uuidtotaldecimalplaced_attimestampplaces
A quoted field name, typed fields, and a one-to-many relation.

Relations and cardinality#

The connector carries the cardinality. N:1 is sugar that swaps the ends, so it reads naturally either direction. A : label adds the verb.

ConnectorCardinality
1:1one to one
1:None to many
N:1many to one (swaps the ends)
N:Mmany to many
->an unspecified link

Relations reference entities by name; entity.field references are accepted and resolve to the entity (the field part is documentation). Unlike graph nodes, a table must be declared: a relation to an undeclared entity is dropped with a diagnostic.

erd
users {
  id uuid pk
}
roles {
  id uuid pk
}
permissions {
  id uuid pk
}

users N:M roles: assigned
roles N:M permissions: grants
Diagramusersid (pk)uuidrolesid (pk)uuidpermissionsid (pk)uuidassignedgrants
Many-to-many relations for a role-based access model.

For a fuller picture, an e-commerce schema tying customers, orders, line items, and products together.

erd
title: Store schema

customers [blue] {
  id uuid pk
  email string
  created_at timestamp
}
orders [green] {
  id uuid pk
  customer_id uuid fk
  status string
  total decimal
}
line_items {
  id uuid pk
  order_id uuid fk
  product_id uuid fk
  quantity int
}
products [orange] {
  id uuid pk
  sku string
  name string
  price decimal
}

customers 1:N orders: places
orders 1:N line_items: contains
products 1:N line_items: sold as
Store schemacustomersid (pk)uuidemailstringcreated_attimestampordersid (pk)uuidcustomer_id (fk)uuidstatusstringtotaldecimalline_itemsid (pk)uuidorder_id (fk)uuidproduct_id (fk)uuidquantityintproductsid (pk)uuidskustringnamestringpricedecimalplacescontainssold as

Looking for classes and methods instead of tables? See UML class diagrams, which share this family but switch to UML boxes and relationship arrows.

Every diagram on these pages is compiled live from the code above it, through the same pipeline the app uses. Open the canvas to try it.