Blueprint Background
cancel Short Answer: No.

Don't Start with the Database.

In Domain-Driven Design, the database is an implementation detail. Starting with tables leads to anemic models. Start with the Domain Model—the heart of your business logic.

The Modeling Approach Viewer

Toggle to see how the starting point drastically changes your code quality.

psychology

The Rich Domain Model

You focus on behavior and invariants. The code speaks the "Ubiquitous Language" of the business. The data structure is secondary to the rules.

  • check_circle Logic is encapsulated in the entity.
  • check_circle Impossible to create invalid state.
  • check_circle Database schema is generated from this.
Customer.java (Domain Entity) Recommended
public class Customer {
    private String id;
    private Email email;
    private boolean isVip;

    // Constructor ensures validity on creation
    public Customer(String id, String email) {
        if (!EmailValidator.isValid(email)) {
            throw new InvalidEmailException();
        }
        this.id = id;
        this.email = new Email(email);
    }

    // Business Action (Behavior)
    public void promoteToVip() {
        if (this.email.isCorporate()) {
             this.isVip = true;
             DomainEvents.raise(new CustomerPromoted(this.id));
        }
    }
}
table_view

The Anemic Model

You focus on tables and columns. The class is just a container for data. Logic leaks into "Service" classes, leading to duplication and inconsistent states.

  • error Public setters allow invalid data.
  • error Logic is separated from data (Low Cohesion).
  • error Thinking in SQL, not business terms.
Customer.java (Data Holder) Anti-Pattern in DDD
public class Customer {
    // Just mapping DB columns
    public String Id { get; set; }
    public String Email { get; set; }
    public boolean IsVip { get; set; }
}

// Logic lives elsewhere (Service Layer)
public class CustomerService {
    public void updateCustomer(Customer c) {
        // Logic is scattered here
        c.setIsVip(true);
        db.save(c);
    }
}

Why Avoid Database-First in DDD?

bloodtype

Anemic Domain Models

Starting with the DB usually results in classes that are just bags of getters and setters. They have no power to enforce business rules, making bugs harder to track.

link_off

Impedance Mismatch

Relational databases (SQL) and Object-Oriented graphs are fundamentally different. Bending your objects to look like tables cripples your ability to use OOP design patterns effectively.

translate

Lost Language

If you talk about "Foreign Keys" and "Join Tables" instead of "Customer Orders" and "Shipping Manifests", you lose the connection with your domain experts.

Build the DDD Workflow

Click the steps in the correct order to simulate a Domain-Driven process.

1
2
3
Start by clicking the first logical step...

Exceptions: When does the DB come first?

While DDD prioritizes the domain, there are real-world scenarios where you must consider the database early:

  • Brownfield Projects: If you are building on top of a massive legacy database, you cannot ignore the existing schema. You might use an Anti-Corruption Layer (ACL) to translate the legacy data into your clean domain model.
  • Performance Constraints: In rare high-performance scenarios, the shape of the data on disk dictates throughput. However, this is usually optimized after the model is understood.
  • Simple CRUD: If the app is just editing tables (e.g., a simple admin panel), DDD is overkill. In that case, Database First is perfectly fine!