The Six Database Patterns That Make Every Blog's Backend Tick
Every backend engineer eventually hits the point where features like likes and tags feel like one-off puzzles. Recognizing them as the same few patterns — junction table, composite key, self-referencing FK, cascade vs. set-null — cuts design time and prevents the kind of ad-hoc schemas that crumble under real query loads.
A blog's social features — liking, bookmarking, commenting, tagging, and file attachments — are not six distinct problems. They are repeated instances of a few core relational patterns. Many-to-many relationships between users and posts (or posts and tags) demand junction tables with composite primary keys, which double as composite indexes and eliminate the need for a surrogate ID. The leftmost prefix rule then dictates when a second single-column index is warranted, and when it would just waste disk and write overhead.
Comments introduce self-referencing via a `parentId` foreign key pointing back to the same table, turning flat rows into threaded trees. Foreign key deletion policies — `ON DELETE CASCADE` for dependent child rows that become meaningless, `ON DELETE SET NULL` for replies that should outlive their parent — encode business logic directly in the schema, reducing reliance on application-level guard code.
Files split storage concerns: the binary lives in OSS or S3, while MySQL holds metadata, ownership, and an optional post association that stays NULL until the draft is published. The entire design ships as a single `blog.sql` file that seeds tables, indexes, and test data, letting any new environment bootstrap instantly.
The article treats database constraints as the first line of defense for business rules — a composite primary key prevents duplicate likes at the storage engine level, which is stronger and cheaper than checking in application code.
Index design is framed as a query-driven decision, not a per-column reflex. The explicit reasoning about when a second index on `postId` is needed (and when an index on `userId` would be redundant) is a concrete application of the leftmost prefix principle that many tutorials gloss over.
The structural similarity between `user_like_post`, `user_collect_post`, and `post_tag` is the real payload: once you internalize the junction-table pattern, features like follows, group memberships, and course enrollments become mechanical, not creative, design tasks.
Self-referencing foreign keys are introduced without drama as a standard tool for tree-shaped data — comments, menus, org charts — which counters the common instinct to reach for recursive CTEs or NoSQL for hierarchical storage.