Stop Starting with SQL: Rethinking How We Design Software

Stop Starting with SQL: Rethinking How We Design Software
Photo by Brecht Corbeel / Unsplash

For decades, developers have been trained—often unconsciously—to begin building software by designing the database. Tables come first, and from those schemas, code is scaffolded, models are generated, and behavior is implemented to match.

But what if this entire process is inside out?

Recently, veteran software engineer Robert C. Martin (known as Uncle Bob) reignited a discussion on this issue, arguing that embedding SQL directly into core logic was one of our industry's most foundational missteps. Regardless of whether you agree with his stance on SQL itself, his larger architectural message deserves deeper reflection.


🧠 Software Architecture Should Start with Behavior, Not Data

Your application exists to serve users, not tables.

When you begin your design with a database schema, you’re making a critical assumption: that your persistence model accurately reflects the business domain. In reality, what’s needed is the opposite.

Start from user stories, not SQL schemas.

Build from the top-down, focusing first on use cases, workflows, and behaviors. Let your domain model evolve organically. Delay touching the persistence layer until the business logic is clear and testable in memory.


🔄 Invert Your Thinking (and Your Dependencies)

One of the central tenets of Clean Architecture is the Dependency Rule: dependencies must always point inward, from outer technical layers to the core business logic—not the other way around.

When you tightly couple your application logic to SQL queries, ORMs, or migration files, you create fragile, rigid systems that are hard to test, hard to evolve, and easy to break.

Instead:

  • Define interfaces that describe what your domain needs (e.g., UserRepository, OrderStorage)
  • Provide an in-memory implementation first for fast iteration and testing
  • Only later, introduce a real database adapter that fulfills the contract

This technique not only improves flexibility—it also gives you room to choose the right persistence strategy, not just the first available one.


🛠️ SQL Is a Tool, Not a Blueprint

SQL isn’t evil. It’s just a technology detail. It doesn’t belong at the center of your design.

Too often, we use SQL as a starting point, which locks us into its limitations:

  • Rigid schemas that resist change
  • Impedance mismatch between objects and tables
  • Coupling to specific relational database assumptions

By putting SQL behind an interface and delaying its adoption, you give your software the space to evolve naturally. You might even discover that some parts of your application need SQL, others might need NoSQL, and still others could just stay in memory or in files.


⚙️ Practical Benefits of Delayed Persistence

  • Improved testability: Run unit tests without needing a live database
  • Faster iteration: Implement domain logic without waiting on migrations
  • Better architecture: Interfaces drive design, not technology choices
  • Future-proofing: Switch out data layers without touching business logic

🧭 Other Considerations Developers Often Miss

  1. Premature Optimization: Picking a DB engine for performance before understanding access patterns is like buying a racecar before knowing where the road leads.
  2. Polyglot Persistence: Different domain modules might require different storage engines. One-size-fits-all rarely works at scale.
  3. Behavior-Driven Development (BDD): Starting from user expectations naturally aligns with this architecture style.
  4. Onboarding Simplicity: New engineers can work on domain code without needing full local DB setups.
  5. Decoupled Environments: Infrastructure decisions (like scaling, sharding, or caching) can evolve independently from the app logic.

📌 Finally

Data persistence should be a plugin, not a foundation.
The database is just one tool among many. Start instead with use cases, build your domain model, and keep persistence at arm’s length until the last responsible moment.

Uncle Bob’s remarks are less about SQL specifically and more about a philosophy: design from the core outwards, not the infrastructure inwards. Your future self—and your teammates—will thank you.

Support Us