DBML Guide: Modeling Databases with Database Markup Language
DBML lets you describe a database in a few readable lines of text and get an ERD from it. It is diagram-as-code for schemas, and this guide covers the syntax and the workflow.
DBML, short for database markup language, is a concise text format for describing a database schema. Instead of drawing entity boxes by hand or writing verbose SQL DDL, you write a few readable lines - a Table block per entity, a Ref line per relationship - and get a structured model you can render as an entity relationship diagram. It is diagram-as-code applied to databases: the schema lives as text that can sit in your repository, be reviewed in pull requests, and version alongside the code, which keeps the diagram honest as the design evolves.
This guide covers the DBML syntax you actually need - defining tables and columns, marking primary and foreign keys, expressing relationships with Ref, and adding indexes - and the workflow of turning DBML into a shareable diagram. You can render and refine the result in Atlas Diagram Studio at /diagrams with the ERD tool at /diagram-tools/erd-tool. Because generating a diagram from DBML keeps it in sync with the written schema, this belongs with the broader approach in the guide on generating diagrams from code at /guides/how-to-generate-diagrams-from-code.
Defining tables in DBML
The core of DBML is the Table block, which describes one entity. Inside it, each line names a column and its type, with optional settings in square brackets for constraints like the primary key, uniqueness, or not-null. It reads far more cleanly than the equivalent SQL, which is much of DBML's appeal - the schema is legible to anyone, not just people fluent in DDL.
Here are two tables defined in DBML:
Table users { id int [pk, increment] email varchar [unique, not null] name varchar created_at timestamp } Table posts { id int [pk, increment] title varchar [not null] author_id int [not null] }
The pk setting marks the primary key, increment makes it auto-incrementing, and unique and not_null add constraints. Each Table becomes an entity box in the ERD, each column an attribute, and the pk column gets a key marker. So far this is just structure; the relationships come next, and they are what turn a list of tables into a connected diagram.
Expressing relationships with Ref
Relationships in DBML are declared with Ref, which connects a column in one table to a column in another and, crucially, encodes the cardinality with a small symbol. The direction of the symbol tells the renderer which side is the one and which is the many, mapping directly onto crow's foot notation in the resulting diagram. This is what makes DBML a true schema-modeling language rather than just a table list - it captures how the tables connect, not only what they contain.
Continuing the example, a single line establishes the relationship between posts and users:
Ref: posts.author_id > users.id
The greater-than symbol means many-to-one: many posts reference one user, so each post has one author and a user can have many posts. DBML uses a small set of these symbols - the angle bracket for many-to-one and one-to-many, a hyphen for one-to-one, and a double angle bracket for many-to-many. A many-to-many Ref signals that a junction table is needed, which you show explicitly on the diagram. Reading these symbols lets you translate any Ref into the correct crow's foot line.
Beyond tables: indexes, enums, and notes
DBML captures more than tables and refs, and using these features makes the model a fuller specification of the schema.
- An indexes block inside a table declares indexes, including composite and unique ones, documenting how the table is queried.
- An Enum block defines a fixed set of allowed values for a column, capturing constraints the diagram can reflect.
- Inline Ref settings can express the relationship right on the column, as an alternative to a separate Ref line.
- A Note can be attached to a table or column to document its meaning, carrying intent into the diagram.
- TableGroup clusters related tables into a subject area, which maps neatly onto grouped regions in the ERD.
- Default values and not-null settings in the column brackets carry modality information for the relationships.
From DBML to a shareable, in-sync diagram
The workflow that makes DBML valuable is keeping the text as the source of truth and generating the diagram from it. Because the DBML file is plain text, it lives in your repository and is edited in the same pull requests that change the schema, so the diagram derived from it never silently drifts. When a reviewer sees the DBML change, they can regenerate the ERD and see the structural consequence visually, which catches modeling mistakes that a text diff alone would hide.
Render the DBML into Atlas Diagram Studio at /diagrams, then use the editor to add the layout, grouping, and annotations that a generator cannot infer - the human touches that make a diagram readable rather than merely correct. DBML is one of several diagram-as-code routes to a schema diagram; the Mermaid ER diagram tutorial at /guides/mermaid-er-diagram-tutorial covers another, and the database design guide at /guides/database-design covers the design principles the notation ultimately serves.