I’ve spent a ridiculous amount of time thinking about database design.
How should entities be modelled? Should this be a separate table? Do we need another relationship? What happens when the data grows? Should we use MySQL on RDS, introduce caching, or consider a document database instead?
And somewhere along the way, database design can become a little like buying a bigger toolbox before you’ve even decided what you’re building.
Then I looked at WordPress.
And honestly, I was amazed.
Wait, that’s it?
WordPress has a relatively small set of core database tables. Depending on the version and configuration, a standard installation commonly starts with around a dozen tables, including tables for posts, post metadata, users, user metadata, comments, terms and options.
Just look at the wp_posts table.
At first glance, you might wonder what on earth is going on here. The table stores much more than what we normally think of as a post. Pages, attachments, menu items and other content types can all be represented through the same underlying structure.
Then comes wp_postmeta, which stores additional information associated with a post.
Need to store a custom property? Metadata.
Need a custom post type? The same underlying content model can support it.
Need categories and tags? WordPress has a taxonomy and term relationship system.
Need plugins to introduce new functionality? They can extend the existing model or create their own tables when appropriate.
Suddenly, the database isn’t trying to predict every possible feature the application might ever need. It provides a relatively small set of building blocks that can be extended.
That’s a surprisingly powerful idea.
SQL vs NoSQL: Must We Really Fight About Everything?
If you’ve spent enough time in software engineering discussions, you’ve probably seen the familiar debate.
SQL is structured. NoSQL is flexible.
SQL is for relationships. NoSQL is for scale.
Someone mentions a new product idea, and before the first endpoint has even been written, we’re debating whether the system needs PostgreSQL, MongoDB, DynamoDB, or a combination of all three.
Sometimes that conversation is necessary. Often, it is premature.
WordPress is a useful reminder that a relational database can support a remarkably flexible application when the data model and application architecture are designed carefully.
The database doesn’t need a new table for every content type. A shared content model, metadata, taxonomies and application-level conventions can cover a surprising number of use cases.
And yes, all of this can sit on MySQL or MariaDB.
Imagine explaining this to someone who has just spent three days designing twelve perfectly normalised tables for a simple content application.
WordPress might politely ask them to take a walk.
The Clever Part Isn’t Just Having Fewer Tables
It would be easy to look at WordPress and conclude that fewer tables automatically mean better design. That’s not the lesson I take from it.
The interesting part is how the tables work together.
1. A common content model
Posts and pages share a common structure. The application distinguishes their behaviour through fields such as content type and status instead of requiring an entirely different table for every variation.
2. Metadata for extensibility
The post metadata model allows plugins and themes to attach additional properties without requiring every installation to modify the core schema.
This is especially useful in an ecosystem where nobody can predict all the features that third-party developers will build.
3. Taxonomies for classification
Categories and tags aren’t simply arbitrary strings scattered across content records. WordPress provides a reusable model for terms and their relationships to content.
4. A stable core with room to extend
Plugins can work within the existing content model or introduce dedicated tables when their requirements justify it.
That last point matters. Flexibility doesn’t mean forcing every piece of data into one table forever. It means providing a foundation that can evolve without redesigning the entire application every time a new requirement appears.
But Isn’t This a Database Design Anti-Pattern?
A fair question.
The metadata approach has trade-offs. Generic key-value metadata can become harder to query efficiently than purpose-built relational tables. Indexing arbitrary metadata, enforcing data types and maintaining complex relationships can be challenging. Some queries become more complicated than they would be in a specialised schema.
And WordPress hasn’t magically solved every scaling problem.
Large WordPress installations may need object caching, page caching, database optimisation, read replicas, a CDN, managed infrastructure or other architectural changes. Plugins can also introduce inefficient queries and unexpected bottlenecks.
But that’s precisely why I find the design interesting.
WordPress doesn’t need to solve every possible scale problem on day one. It provides a useful general-purpose foundation, and the deployment can evolve as the workload demands it.
Not every website needs to process a thousand requests per second. Some sites need articles, a handful of plugins, a contact form and a database that behaves itself.
Building a distributed system for that workload might be technically impressive, but it could also be the software equivalent of bringing a crane to hang a picture.
Scale When You Need It, Not Because It Sounds Impressive
This is the part I keep coming back to.
We often design systems around hypothetical future requirements. Millions of users. Billions of records. Global availability. Complex event pipelines. Multiple data stores.
Those requirements are real for some products. They are not universal requirements for every application.
WordPress demonstrates a different starting point: build a useful system with a relatively small core, make it extensible, and introduce complexity where the actual requirements demand it.
And when a WordPress site does grow, there are ways to scale it. Managed database services such as Amazon RDS can reduce operational overhead. Caching can reduce repeated database work. CDNs can serve static assets closer to users. More advanced deployments can introduce replicas and other infrastructure.
None of these makes scaling effortless, and managed services don’t eliminate architectural bottlenecks. But they give site owners options without requiring every small site to begin with a complicated distributed architecture.
Sometimes the best architecture is the one that lets you launch, learn and improve without spending the first six months maintaining infrastructure nobody needs yet.
What I’m Taking Away From This
I don’t think WordPress proves that every application should use a small number of generic tables. Nor does it mean normalisation, relational modelling or NoSQL databases are unnecessary.
It proves something more useful: good architecture is about choosing the right abstractions for the problem, not maximising the number of tables, services or technologies involved.
A small, well-designed core can support an enormous ecosystem when the extension points are thoughtfully chosen.
And a relational database can be more flexible than we sometimes give it credit for.
After spending so much time thinking about entities, schemas, scaling strategies and data stores, I find that genuinely refreshing.
Maybe the next time I start designing a system, I’ll ask a slightly different question before drawing the entity relationship diagram:
What is the simplest model that can solve the problem today, while leaving us room to grow tomorrow?
Because sometimes the cleverest database design isn’t the one with the most elegant diagram.
Sometimes it’s the one that quietly powers millions of websites while the rest of us are still arguing about which database to use.
