Back to Blog
Tech

Why Databases Need All This Ceremony (Data Explained)

Developers talk about databases like they're handling explosives. Migrations. Backups. Environment separation. From the outside, it looks like paranoia.

Why Databases Need All This Ceremony (Data Explained)

Developers talk about databases like they're handling explosives. Migration scripts. Rollback procedures. Backup strategies. Environment separation. Testing against "real" databases.

From the outside, it looks like paranoia. It's just a place to store data, right? Why all the ceremony?

Because data is different from code. When something goes wrong with code, you fix it and redeploy. When something goes wrong with data, you might have just deleted someone's wedding photos.

This post explains why databases get special treatment—and why the overhead is worth it.

The Difference Between Code and Data

Code is like a recipe. If your recipe says "bake at 450°" but should say "350°", you fix the recipe. No cake was harmed in the making of this fix. Tomorrow, everyone uses the corrected recipe.

Data is like the cake itself. Once you've baked it wrong, you can't unbake it. The eggs are already in there. The damage is done.

When you deploy code, you're replacing one set of instructions with another. When you modify a database, you're changing actual information that real people put there.

This fundamental difference drives everything.

Why Data Changes Are One-Way Doors

Let's say you have a database with a million customer records. Each customer has a "phone number" field.

You decide to "improve" things by splitting this into "country code" and "local number." Seems sensible. You write a script to convert all the existing data.

But something goes wrong. Your script has a bug. Half the numbers get mangled.

Can you undo it? Not easily. The original data is gone. It was overwritten. Unless you have a backup (and tested restoring it), those phone numbers are history.

This is why database changes are called migrations—you're migrating data from one structure to another. And unlike code deployments, there's often no simple rollback. You can't un-scramble an egg.

The Environment Problem

Developers typically work in three or more environments:

Development — Your local machine. Break things freely. Nobody else is affected.

Staging — A shared testing area. Realistic data, but not real customers.

Production — The real thing. Real customers. Real money. Real consequences.

For code, moving between these environments is straightforward. Same code, different servers.

For databases, it's a nightmare. Each environment has its own data. You can't just copy production to development (privacy, scale, compliance). But you can't test data changes without data.

So you end up with elaborate setups:

  • Anonymized copies of production data for staging
  • Synthetic data for development
  • Careful scripts that work across all environments
  • Verification steps to ensure changes actually applied

All this infrastructure exists because data is state, and state is hard.

Why Not Just Copy Production?

The obvious solution: just copy the production database to staging and test there.

Problems:

  1. Privacy laws: Customer data often can't legally leave production systems. GDPR, HIPAA, etc.
  2. Scale: Production databases are often terabytes. Copying is slow and expensive.
  3. Data sensitivity: Real credit card numbers, real addresses, real medical records. Too risky to spread around.
  4. Timing: By the time you copy, production has changed. Your test is already stale.

This is why companies build data anonymization pipelines—software that copies the structure and patterns of real data without the sensitive details.

The Testing Trap

Here's a trap I fell into early in my career:

For speed, I tested my code against a "fake" database that lived entirely in memory. It was fast. It was convenient. My tests passed.

Then I deployed to production, and everything exploded.

Why? The fake database was too forgiving. It accepted queries that a real database would reject. The fake database didn't enforce constraints the real database did. My tests were testing a fiction.

The lesson: test against what you'll actually use. A test that passes against a pretend database and fails against a real one is worse than no test at all—it gives false confidence.

Modern database testing uses real database engines, running in containers, automatically created and destroyed for each test. Slower, but honest.

Migrations: Scripted Change

Because database changes are so risky, developers don't make them manually. Instead, they write migration scripts—small, versioned programs that modify the database structure in a controlled way.

Migration #1 might create a table. Migration #2 adds a column. Migration #3 renames something. Migration #4 deletes old data.

Each migration is tested. Each is versioned. Each is applied in order. You can see exactly what changed, when, and why.

It's like a detailed changelog for your data structure. If something goes wrong, you can trace back to the exact change that caused it.

Encryption: Secrets at Rest

Data sitting in a database is called "data at rest." Even if your application is secure, what happens if someone steals the physical hard drive? Or accesses your database backups?

If the data is plaintext, they can read everything.

If the data is encrypted, they see gibberish.

This is why sensitive fields—passwords, API keys, personal information—get encrypted before storage. Even if an attacker gets the database dump, they can't read it without the encryption key.

The key itself becomes precious. Store it separately. Rotate it periodically. Never commit it to version control.

Backups: Because Things Fail

Hard drives fail. Data centers flood. Ransomware encrypts everything. Human error deletes production tables.

Backups are your insurance policy. But having backups isn't enough—you need to actually test restoring from them.

"We have backups" means nothing if you've never verified that the restoration process works. Companies have gone bankrupt discovering their backups were corrupt only after they needed them.

The rule: if you haven't restored from a backup recently, you don't have backups. You have hopes.

Why This Matters to Non-Developers

Even if you never write code, understanding database ceremony helps you understand:

Why software projects take so long: Data changes require extensive testing that code changes don't.

Why migrations are scheduled carefully: It's not bureaucracy—it's risk management.

Why old systems are hard to replace: Data migration is the scary part, not code rewriting.

Why companies are paranoid about data: Once it's gone, it's gone. Once it's leaked, it can't be unleaked.

The Simple Takeaway

Databases get special treatment because:

  • Data changes can't be easily undone — there's no "ctrl-Z" for a million corrupted records
  • Production data is real — real customers, real consequences
  • Environments differ — what works in testing might break in production
  • Fake databases lie — they don't catch real errors
  • Backups must work — having them means nothing if you can't restore them
  • Encryption protects at rest — because breaches happen

All the ceremony exists because data is the actual reason software exists. The code is just instructions. The data is the thing being protected, processed, and preserved.

Treat it accordingly.


This is part of the ELI5 series—technical concepts explained without the jargon. For detailed patterns on database testing and migrations, see Modern Database Testing and Schema-Aware EF Core Migrations.

Data is not just files. It's trust.

Comments

More in Tech