A complete guide to choosing between relational (SQL) and non-relational (NoSQL) databases. Compare ACID vs BASE, scaling strategies, and real-world database examples.
SQL databases (relational) store data in tables with a fixed schema. Relationships between data are defined upfront. They enforce ACID transactions.
NoSQL databases store data in flexible formats — documents, key-value pairs, wide columns, or graphs. Schema is flexible. They typically trade consistency for scale and performance.
Neither is universally better. The right choice depends on your data model, access patterns, and scale requirements.
Data is organized into tables (rows and columns). Relationships are expressed through foreign keys and joins.
-- Users table
id | name | email
1 | Alice | alice@example.com
-- Orders table
id | user_id | total | created_at
1 | 1 | 99.99 | 2025-01-01Examples: PostgreSQL, MySQL, SQLite, Oracle, SQL Server
NoSQL is not one thing — it's four distinct types, each optimized for different use cases.
Store data as JSON/BSON documents. Each document can have a different structure.
{
"_id": "user_123",
"name": "Alice",
"address": { "city": "Mumbai", "zip": "400001" },
"orders": [{ "id": "ord_1", "total": 99.99 }]
}Strengths: Flexible schema, natural fit for object-oriented data, easy to scale reads Weaknesses: No joins (must denormalize), eventual consistency by default Use when: Content management, user profiles, product catalogs Examples: MongoDB, CouchDB, Firestore
The simplest NoSQL type — a giant hash map. Store and retrieve values by key.
SET user:123:session "abc123xyz" EX 3600
GET user:123:session → "abc123xyz"
Strengths: Extremely fast (O(1) reads/writes), simple, scales easily Weaknesses: No query capability beyond key lookup, no relationships Use when: Caching, sessions, rate limiting, leaderboards Examples: Redis, DynamoDB (as key-value), Memcached
Store data in tables but columns can vary per row and are grouped into column families. Optimized for writes and time-series data.
Row key: user_123
activity:2025-01-01 → "login"
activity:2025-01-02 → "purchase"
activity:2025-01-03 → "logout"
Strengths: Massive write throughput, excellent for time-series, scales to petabytes Weaknesses: Limited query patterns, no joins, eventual consistency Use when: IoT data, activity feeds, analytics, time-series Examples: Cassandra, HBase, Google Bigtable
Store data as nodes and edges. Optimized for traversing relationships.
(Alice) -[FOLLOWS]→ (Bob)
(Bob) -[FOLLOWS]→ (Charlie)
Query: Who does Alice follow transitively?
Strengths: Natural for relationship-heavy data, fast graph traversals Weaknesses: Niche use case, harder to scale, less tooling Use when: Social networks, recommendation engines, fraud detection, knowledge graphs Examples: Neo4j, Amazon Neptune, ArangoDB
Ask these questions in order:
Most large systems use multiple databases:
| Data | Database | Why |
|---|---|---|
| Users, orders, payments | PostgreSQL | ACID, relational |
| Sessions, rate limits | Redis | Fast key-value |
| Product search | Elasticsearch | Full-text search |
| Activity/events | Cassandra | High write throughput |
| Recommendations | Neo4j | Graph traversal |
| SQL | NoSQL | |
|---|---|---|
| Schema | Fixed | Flexible |
| Transactions | ACID | Eventual (usually) |
| Scaling | Vertical (mostly) | Horizontal |
| Queries | Flexible (any JOIN) | Limited to access patterns |
| Best for | Relational, transactional | Scale, flexibility, specific patterns |
Default to SQL (PostgreSQL) unless you have a specific reason not to. It handles most use cases well and is easier to reason about. Add NoSQL databases when you hit specific limitations.