Blog Database Schema database schema
The Blog Database Schema database schema is a DB Planner template with 15 tables, 114 columns and 19 relationships, free to use. Core tables include categories, comment_reports, comments, media. It can be opened as an interactive diagram or exported as PostgreSQL, MySQL, or MSSQL DDL.
- Tables
- 15
- Columns
- 114
- Relationships
- 19
- Category
- CMS
- Exports
- DBML, SQL, C#
- Price
- Free
What this schema models
A blog database schema designed around the two things that actually decide whether a content site survives: stable URLs and a real revision history. 15 tables and 6 enums covering authors and roles, posts with full version history, hierarchical categories and flat tags, a reusable media library, threaded comments with moderation, double opt-in subscribers, SEO metadata, redirects and pre-aggregated view analytics. THE TWO DECISIONS 1. The SLUG is the product. Every public URL is a slug, slugs are unique, and once a post is published its slug is treated as immutable. Changing one writes a row in redirects rather than editing the post in place. A blog that quietly changes URLs throws away every backlink it ever earned — the redirects table with its 301/302 status_code and hit_count is what makes a restructure survivable, and shows you which old URLs still carry traffic. 2. Post body is VERSIONED. posts holds the current live state; post_revisions holds every prior version with an editor, a revision number and a change summary. Publishing is a timestamp, not a separate table — and a published_at in the future IS the scheduling mechanism, so there is no queue table to drift out of sync with reality. DETAILS WORTH STEALING - Categories are few, curated and hierarchical; tags are many, flat and author-created. They are deliberately separate tables because they behave differently, and post_categories.is_primary picks the one used for breadcrumbs and the canonical URL. - seo_meta uses meta_title varchar(70) and meta_description varchar(160) on purpose — those are roughly what a search result actually renders, so the schema itself stops an editor writing something that will be truncated. - media is a reusable library with a many-to-many join, so one image can appear in several posts without being re-uploaded. alt_text is treated as required in practice: it is both accessibility and image search. - Comments allow guests, which is why author_name and author_email are denormalised onto the row and user_id is nullable. Self-referencing parent_id gives threads. - Subscribers use double opt-in: confirmed_at null means pending and must never be mailed. Unsubscribe is a timestamp, never a delete, so a careless re-import cannot resurrect someone who opted out. - post_views is pre-aggregated per post per day per referrer rather than one row per hit. Raw hit logs belong in an analytics pipeline, not in the blog database. WHAT YOU GET Clean DBML that imports straight into DB Planner, plus a laid-out board with cards colour-coded by zone — people, content, taxonomy, media, comments, and SEO & analytics — with sticky notes explaining each decision and every table carrying its own Note. Postgres-flavoured types that port cleanly to MySQL or SQL Server. Useful for developers building a blog or publishing platform, anyone moving off WordPress or Ghost to something custom, students who need a realistic blog ER diagram, and content teams who want the SEO model designed in from the start rather than bolted on later.
Tables (15)
| Table | Columns |
|---|---|
| categories | 6 |
| comment_reports | 7 |
| comments | 11 |
| media | 12 |
| post_categories | 3 |
| post_media | 3 |
| post_revisions | 8 |
| post_tags | 2 |
| post_views | 6 |
| posts | 15 |
| redirects | 7 |
| seo_meta | 11 |
| subscribers | 9 |
| tags | 4 |
| users | 10 |
Relationships (19)
categories.parent_id references categories.idmany to onecomment_reports.comment_id references comments.idmany to onecomments.parent_id references comments.idmany to onecomments.post_id references posts.idmany to onecomments.user_id references users.idmany to onemedia.uploaded_by references users.idmany to onepost_categories.category_id references categories.idmany to onepost_categories.post_id references posts.idmany to onepost_media.media_id references media.idmany to onepost_media.post_id references posts.idmany to onepost_revisions.editor_id references users.idmany to onepost_revisions.post_id references posts.idmany to onepost_tags.post_id references posts.idmany to onepost_tags.tag_id references tags.idmany to onepost_views.post_id references posts.idmany to oneposts.author_id references users.idmany to oneposts.featured_media_id references media.idmany to oneseo_meta.category_id references categories.idmany to oneseo_meta.post_id references posts.idmany to one
How to use this template
- Open the diagram to see the tables and how they relate.
- Copy it into your workspace. You get your own editable copy.
- Export it as PostgreSQL, MySQL, or MSSQL DDL, or as C# models.
Frequently asked questions
- What is in the Blog Database Schema schema?
- 15 tables and 19 relationships, across 114 columns. The table names and the full relationship list are shown on this page.
- Can I export it to PostgreSQL or MySQL?
- Yes. Every DB Planner template exports as DBML, PostgreSQL, MySQL, or MSSQL DDL, and as C# models.
- Is this template free?
- Yes. You can open it in the browser without an account, and copy it into your own workspace with a free DB Planner account.
- Can I change it after copying it?
- Yes. A copy is yours: you can rename tables, add columns, and export it. Changes the author makes later do not affect your copy.