Database Guidelines

These guidelines cover how OSBR chooses a data store and structures relational schemas. They are the detailed companion to the Infrastructure Planning Policy β€” that page sets the high-level principles; this one is the database how-to. The Technical Glossary defines the underlying terms.

Like the rest of our infrastructure guidance, this leans on the decision guides the large cloud vendors publish and right-sizes them for an SME.

1. Choosing a Data Store: SQL vs NoSQL

Follow the industry: default to a relational SQL database, and choose NoSQL only when a concrete requirement makes relational a poor fit. Most application data is relational, and a good relational database handles the overwhelming majority of workloads.

Structure the decision the way the major vendors do β€” their decision guides are exactly the kind of big-tech reference an SME can adopt wholesale:

1-1. Default to Relational SQL

Reach for SQL (relational) when β€” which is most of the time:

Default engine: PostgreSQL

For structured SQL, PostgreSQL is the industry default and OSBR's default choice. Prefer a serverless / scale-to-zero flavour where it fits our scale-to-zero principle: Cloudflare D1 (SQLite) for small, edge-local, read-heavy data; a serverless Postgres for anything with real relational depth, concurrency, or write load.

1-2. Reach for NoSQL Deliberately

Choose a non-relational store only when a specific access pattern or scale requirement pushes you there. Match the type of NoSQL to the job, as the vendor decision guides lay out:

Type Good for Examples
Key-value Cache, sessions, config, feature flags β€” access by a single key Cloudflare KV, DynamoDB, Redis
Document Records whose shape varies; denormalized, read-optimized data accessed by key DynamoDB, Firestore, MongoDB
Object / blob Files, images, backups, large binaries β€” not a database Cloudflare R2, S3
Wide-column / other Extreme write throughput with known, narrow access patterns Cassandra, Bigtable

Signs NoSQL is the right call:

Don't pick NoSQL for scale you don't have

Choosing NoSQL "to scale" before you have the scale trades away joins, transactions, and query flexibility for a problem you may never hit. Airbnb, at far larger scale than us, kept its primary store on relational MySQL and scaled it by partitioning rather than switching to NoSQL. Start relational, and move specific hot paths to NoSQL when a measured need appears.

1-3. Quick Decision Guide

Consideration Lean SQL Lean NoSQL
Relationships & joins Many Few / none
Transactions & consistency Strong (ACID) needed Eventual is fine
Query flexibility Ad-hoc / reporting Fixed, key-based
Schema Known and stable-ish Flexible / varies per record
Scale pattern Vertical + read replicas Extreme horizontal
Data shape Tabular / relational Document / key-value / blob
Polyglot persistence is normal

A single system often uses more than one store: PostgreSQL for core relational data, a key-value store for cache and sessions, and object storage for files. AWS explicitly endorses this polyglot persistence β€” use the right tool per concern rather than forcing everything into one.

2. Structuring a SQL Schema: What to Consider

When you do use relational SQL, follow standard industry practice. This section is about the decisions, grounded in the same big-tech guidance.

2-1. Model the Domain, Normalize First

2-2. Keys and Identity

2-3. Enforce Invariants in the Database

The database is the last line of defense β€” do not rely on application code alone.

2-4. Types and Precision

2-5. Indexing

2-6. OSBR SQL Style (House Decisions)

This is OSBR's SQL style β€” decided, not a menu. It aligns with the GitLab and Mozilla style guides where they agree, but the rules below are ours and are what we hold pull requests to. Don't re-litigate them per PR.

2-7. Migrations and Evolution

2-8. Plan for Access Patterns and Growth

2-9. Security and Privacy

3. References

Data-store and SQL guidance this page draws on:

Choosing a data store

Schema design & SQL style