Schema-on-Read and Schema-on-Write

Schema-on-Read vs Schema-on-Write

Schema-on-Write (Traditional relational databases):

  • Schema is enforced when data is written to the database

  • The database validates and rejects data that doesn't match the schema

  • All data must conform to a single, predefined structure

  • "Write on schema" - you must know the structure before storing data

Schema-on-Read (Document/NoSQL databases):

  • Schema is interpreted when data is read from the database

  • The database stores data without validation

  • Data can have varying structures; the application interprets it

  • "Schemaless" or "flexible schema" - structure determined at query time

Visual Comparison

Schema-on-Write (SQL):
User → Application → [Schema Validation] → Database
                           ↑ (rejects invalid data)
                     Structure enforced here

Schema-on-Read (NoSQL):
User → Application → Database (stores anything)

         Structure interpreted here when reading

Schema-on-Write

Strict Structure Enforcement

Characteristics

  • Structure first: You define tables, columns, types, and constraints upfront

  • Validation at write time: Invalid data is rejected immediately

  • Uniform data: All records have the same structure

  • Schema changes are expensive: Requires migrations that affect all existing data

Advantages

  • Data integrity: Guarantees all data is valid and consistent

  • Catches errors early: Invalid data is rejected immediately

  • Query optimization: Database knows exact structure, can optimize queries

  • Documentation: Schema serves as explicit documentation

  • Type safety: Enforces data types strictly

Disadvantages

  • Rigid: Changing schema requires migrations

  • Downtime risk: Schema changes can lock tables

  • Slower iteration: Must plan schema changes carefully

  • Handles variability poorly: Difficult to store heterogeneous data

Common in

  • Relational databases (PostgreSQL, MySQL, Oracle)

  • Traditional SQL databases

  • Systems prioritizing consistency and integrity


Schema-on-Read

Flexible Structure Storage

Reading with Schema Interpretation

Schema Evolution Over Time

Characteristics

  • Write flexibility: Can store any structure without predefinition

  • Validation at read time: Application handles interpretation and validation

  • Heterogeneous data: Different records can have different structures

  • Schema evolution is easy: Just start writing new formats

Advantages

  • Flexibility: Easy to add new fields or change structure

  • Rapid iteration: No migrations needed for schema changes

  • Handles evolution: Old and new data formats coexist naturally

  • Semi-structured data: Great for varying or unpredictable structures

  • No downtime: Schema changes don't require database operations

Disadvantages

  • No guarantees: Data might be invalid, incomplete, or inconsistent

  • Errors appear late: Problems discovered during reads, not writes

  • Application complexity: Validation logic scattered in application code

  • Harder to optimize: Database can't assume structure for query optimization

  • Documentation burden: Schema exists implicitly in code

Common in

  • Document databases (MongoDB, CouchDB)

  • Key-value stores (Redis with JSON)

  • Column-family stores (Cassandra)

  • Data lakes and big data systems


Golang Example: Comparing Both Approaches

Schema-on-Write (PostgreSQL)

Schema-on-Read (MongoDB)

Handling Schema Changes

Schema-on-Write: Requires Migration

Schema-on-Read: No Migration Needed

Key Differences Summary

Aspect
Schema-on-Write
Schema-on-Read

When validated

At write time

At read time

Where schema lives

In database

In application code

Data uniformity

All data matches schema

Data can vary in structure

Schema changes

Requires migrations

Just update application code

Error detection

Immediate (write fails)

Delayed (read time)

Data integrity

Guaranteed by database

Responsibility of application

Best for

Structured, consistent data

Semi-structured, evolving data


Hybrid approach

What's happening here:

This uses a relational database (PostgreSQL) but adds a JSON column for flexible data. The table structure is strict, but one column can hold any JSON.

Complete SQL Example

Full Golang Example


The choice fundamentally reflects a trade-off between flexibility and safety—schema-on-write prioritizes correctness and consistency, while schema-on-read prioritizes adaptability and speed of change.


Last updated