The Day My “Simple” Database Design Collapsed Under Real Users

I am a full-stack developer (currently working with cognizant) who is passionate about web development and creating digital products with innovative solutions.
I hold 6+ years of experience in development, understanding clients' unique needs, and delivering quality code. I've honed my coding skills over these years through both my professional exposure and self-study. Have worked with teams that have used agile development methodology.
I am someone who likes to keep acquiring new skills and capabilities. And when I am not a web developer, I enjoy reading, writing and running.
My interests include:
- Exploring new ideas
- Learning about future tech & products
- Finding user-friendly solutions to tech-related problems
- Sharing my knowledge with close acquaintances
It started with confidence.
I had built what I thought was a clean schema for a social media app. One table. Everything inside it.
Users, posts, likes, comments—just neatly packed together.
It worked perfectly…
Until it didn’t.
Queries slowed down. Data duplicated. Relationships got messy. And the worst part?
I couldn’t even answer a simple question like:
“Who liked this photo?”
Without writing a monster query that felt like decoding ancient scripts.
That’s when I realized:
Good database design isn’t about storing data. It’s about modeling reality correctly.
The Roadmap
In this guide, we are going to explore 6 key concepts to help you master relational database design using a real-world social media schema:
Why normalization matters
Breaking systems into entities
One-to-many relationships (users → photos, comments)
Many-to-many relationships (likes, tags)
Self-referencing relationships (follows)
Production insights (scaling, performance, real-world systems)
1. Why You Can’t Store Everything in One Table
Let’s start with the mistake I made.
I tried this:
users + photos + comments + likes + tags → ONE TABLE
It felt efficient.
It was not.
Why It Matters (Production Reality)
When everything lives in one table:
Data gets duplicated
Updates become inconsistent
Queries become slow
Relationships become unclear
This is exactly what normalization solves.
Analogy: A Messy Warehouse
Imagine a warehouse where:
Clothes
Electronics
Food
…are all dumped in one room.
Now try finding something.
That’s your database without normalization.
Debug Scenario
What happens if this fails?
Same user stored multiple times
Updates don’t sync
Reports become inaccurate
Senior Dev Perspective 💡
If your table starts feeling like a “dumping ground,” you’ve already lost.
2. Entities — Modeling the Real World Correctly
Real systems don’t think in tables.
They think in entities.
From the schema:
users
photos
comments
likes
follows
tags
photo_tags
Each represents a real-world concept.
Why It Matters
Separating entities allows:
Clean relationships
Scalable design
Efficient queries
Analogy: A City
Think of a social network as a city:
Users → citizens
Photos → billboards
Comments → conversations
Likes → approvals
Follows → friendships
Each has its own place.
Debug Scenario
What happens if this fails?
Mixing entities leads to confusion
Relationships break
Data becomes unreliable
Senior Dev Perspective 💡
Design your schema like you're modeling reality—not just writing SQL.
3. One-to-Many Relationships — The Backbone
Example: Users → Photos
1 user → many photos
CREATE TABLE photos (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
image_url VARCHAR(255) NOT NULL,
user_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id)
);
Why It Matters
This relationship ensures:
Each photo belongs to a user
Data stays connected
Queries remain simple
Analogy: Author & Books
One author writes many books.
But each book has one author.
Same idea.
Debug Scenario
What happens if this fails?
Photos without owners
Broken references
Orphaned data
Senior Dev Perspective 💡
Foreign keys are not optional—they’re your safety net.
4. Many-to-Many Relationships — Where Things Get Interesting
Example: Likes
A user can like many photos.
A photo can be liked by many users.
Solution:
CREATE TABLE likes (
user_id INTEGER NOT NULL,
photo_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id),
FOREIGN KEY(photo_id) REFERENCES photos(id),
PRIMARY KEY(user_id, photo_id)
);
Why It Matters
This prevents:
Duplicate likes
Data inconsistency
Analogy: Students & Courses
One student → many courses
One course → many students
You need a middle table.
Debug Scenario
What happens if this fails?
Duplicate likes
Inflated counts
Broken analytics
Senior Dev Perspective 💡
Junction tables are where clean design meets real-world complexity.
5. Self-Referencing Relationships — Modeling Human Behavior
Example: Follows
CREATE TABLE follows (
follower_id INTEGER NOT NULL,
followee_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(follower_id) REFERENCES users(id),
FOREIGN KEY(followee_id) REFERENCES users(id),
PRIMARY KEY(follower_id, followee_id)
);
Why It Matters
Users relate to other users.
This is different from normal relationships.
Analogy: Friendships
In real life:
You follow someone
Someone follows you
Same table. Different roles.
Debug Scenario
What happens if this fails?
Invalid relationships
Duplicate follows
Logical inconsistencies
Senior Dev Perspective 💡
Self-referencing tables are simple to write—but tricky to reason about.
6. Tags & Flexibility — Designing for Growth
Example: Tags + Photo Tags
CREATE TABLE tags (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
tag_name VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE photo_tags (
photo_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
FOREIGN KEY(photo_id) REFERENCES photos(id),
FOREIGN KEY(tag_id) REFERENCES tags(id),
PRIMARY KEY(photo_id, tag_id)
);
Why It Matters
Tags allow:
Flexible categorization
Search features
Discoverability
Analogy: Labels on Files
Instead of storing files in one folder:
Add labels
Filter easily
Debug Scenario
What happens if this fails?
Duplicate tags
Poor search
Bad user experience
Senior Dev Perspective 💡
Design for features you don’t have yet—tags are future-proofing.
7. Performance & Production Reality — Where Theory Meets Scale
From real-world systems:
What Changes in Production?
You don’t just have tables.
You have:
millions of rows
high traffic
complex queries
Key Techniques
Indexes on foreign keys
Read replicas
Caching (Redis)
CDN for images
Async queues
Critical Insight
Photos are NOT stored in DB.
Only this is stored:
image_url
Actual images → S3 / CDN
Analogy: Library System
The database is a catalog.
The actual books? Stored elsewhere.
Senior Dev Perspective 💡
Databases store references—not heavy assets.
8. The Real Skill — Asking Better Questions
Example Query
SELECT *
FROM users
ORDER BY created_at
LIMIT 5;
This finds:
5 oldest users
Why It Matters
Good schema design makes queries:
Simple
Fast
Understandable
Bad schema?
Everything becomes painful.
The Bridge (Back to That Broken Design)
That messy one-table design I started with?
It didn’t fail because SQL is hard.
It failed because I didn’t understand how systems scale.
This schema taught me something deeper:
Clean database design isn’t about tables—it’s about thinking in relationships.
And once you see it…
You can’t unsee it.



