Mermaid exampleEntity Relationship

Blog CMS Database ER Diagram: Posts, Tags, and Comments

A blog schema is small enough to fit on one screen and still contains the two patterns every content system needs: a one-to-many from authors to posts, and a many-to-many between posts and tags. That makes this diagram a common teaching example and a practical starting point for a real CMS.

  • blog database schema
  • cms er diagram
  • many to many er diagram
  • posts tags comments schema
  • mermaid erdiagram
Blog CMS Database ER Diagram: Posts, Tags, and Comments

writes

writes

receives

tagged

labels

embeds

USER

int

id

PK

string

username

UK

string

email

UK

string

role

POST

int

id

PK

int

author_id

FK

string

slug

UK

string

status

datetime

published_at

COMMENT

POST_TAG

int

post_id

FK

int

tag_id

FK

TAG

MEDIA

Open in editor → 24 linesrenders in GitHub, Notion, Obsidian

Mermaid code

erDiagram
    USER ||--o{ POST : writes
    USER ||--o{ COMMENT : writes
    POST ||--o{ COMMENT : receives
    POST ||--o{ POST_TAG : tagged
    TAG ||--o{ POST_TAG : labels
    POST ||--o{ MEDIA : embeds
    USER {
        int id PK
        string username UK
        string email UK
        string role
    }
    POST {
        int id PK
        int author_id FK
        string slug UK
        string status
        datetime published_at
    }
    POST_TAG {
        int post_id FK
        int tag_id FK
    }

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 join entity POST_TAG carries the many-to-many. Both POST ||--o{ POST_TAG and TAG ||--o{ POST_TAG are one-to-many, which together express that a post has many tags and a tag has many posts. USER connects to both POST and COMMENT, and COMMENT points back to POST, so a comment always knows its post and its author. UK marks the unique columns: username, email, and slug. COMMENT, TAG, and MEDIA appear through relationships only; give them attribute blocks once the columns are decided.

How to adapt it

  • Add int parent_id FK to COMMENT and a self-relationship COMMENT ||--o{ COMMENT : replies for threaded comments.
  • Split string role into a ROLE entity if users can hold several roles.
  • Add a CATEGORY entity with POST }o--|| CATEGORY : "filed under" for a single required category per post.
  • Add int revision and a POST_REVISION entity if editors need version history.

FAQ

Why does POST_TAG have no primary key marker?

Its primary key is the pair of foreign keys. Mermaid lets you mark both columns with PK, FK in one attribute line, for example int post_id PK, FK, if you want the composite key shown explicitly.

How do I draw a many-to-many without the join table?

Write POST }o--o{ TAG : tagged. The diagram gets shorter but hides where the relationship is stored, so most teams keep the join entity once the schema is implemented.