Databases Overview
Choosing the right database is critical for modern applications. This guide explores different database types, technologies, and cloud vendors to help you make informed decisions for your JavaScript/TypeScript projects.
Database Categories
Relational Databases (SQL)
What they are:
- Structured data in tables with rows and columns
- Relationships between tables using foreign keys
- ACID guarantees (Atomicity, Consistency, Isolation, Durability)
- Strong consistency
- SQL query language
Best for:
- Transactional applications (e-commerce, banking)
- Complex queries and joins
- Data integrity requirements
- Traditional business applications
Technologies:
- PostgreSQL - Most popular open-source relational database
- CockroachDB - Distributed SQL with global scale
- MySQL/MariaDB - Widely used, simple to get started
Document Databases (NoSQL)
What they are:
- Store data as JSON-like documents
- Flexible schema
- Horizontal scaling
- Eventually consistent (usually)
Best for:
- Rapid development with changing requirements
- Unstructured or semi-structured data
- High-volume read/write operations
- Content management systems
Technologies:
Key-Value Stores
What they are:
- Simple key-value pairs
- Extremely fast reads/writes
- In-memory or persistent
- Limited query capabilities
Best for:
- Caching
- Session storage
- Real-time analytics
- Rate limiting
Technologies:
- Redis - In-memory data structure store
Data Warehouses
What they are:
- Optimized for analytical queries
- Column-oriented storage
- Handle massive datasets
- Aggregation and reporting
Best for:
- Business intelligence
- Analytics and reporting
- Historical data analysis
- Large-scale aggregations
Technologies:
- BigQuery - Google's serverless data warehouse
Edge Databases
What they are:
- Run close to users (edge locations)
- Low latency
- Global distribution
- Optimized for serverless
Best for:
- Global applications
- Edge computing
- Serverless functions
- Low-latency requirements
Technologies:
Cloud Database Vendors
PostgreSQL Providers
- Neon - Serverless Postgres with branching
- Supabase - Postgres + Auth + Storage + Realtime
- Amazon RDS - Managed relational databases
- Google Cloud SQL - Managed PostgreSQL
MySQL Providers
- PlanetScale - Serverless MySQL with branching (vitess-based)
- Amazon RDS - Managed MySQL
- Google Cloud SQL - Managed MySQL
SQLite at the Edge
- Cloudflare D1 - SQLite at Cloudflare's edge
- Turso - LibSQL at the edge with replication
MongoDB Providers
- MongoDB Atlas - Official cloud offering
- Amazon DocumentDB - AWS-managed MongoDB-compatible
Database Acceleration
- Cloudflare Hyperdrive - Connection pooling and caching for edge databases
Database Comparison
Database | Type | Best For | Consistency | Scale | Edge |
---|---|---|---|---|---|
Postgres | SQL | General purpose | Strong | Vertical + Horizontal | No |
CockroachDB | SQL | Global scale | Strong | Horizontal | Yes |
MongoDB | NoSQL | Flexible schema | Eventual | Horizontal | No |
Firebase | NoSQL | Real-time apps | Eventual | Horizontal | No |
Redis | Key-Value | Caching | Strong | Horizontal | No |
BigQuery | Data Warehouse | Analytics | Strong | Massive | No |
Turso | SQL (Edge) | Low latency | Eventual | Edge replication | Yes |
LibSQL | SQL (Local) | Embedded/Local | Strong | Single instance | No |
Choosing a Database
For Web Applications
Traditional (Centralized):
User → Server → [Postgres/MongoDB] (Single Region)
Best Choice:
- Postgres via Supabase or Neon
- Strong consistency, ACID guarantees
- Rich ecosystem, mature tooling
- Full-text search, JSON support
For Global Applications
Edge (Distributed):
User (Tokyo) → Edge Server (Tokyo) → [Turso] (Replicated)
User (London) → Edge Server (London) → [Turso] (Replicated)
Best Choice:
- Turso for SQL at the edge
- CockroachDB for strong consistency globally
- Low latency worldwide
- Automatic replication
For Real-Time Applications
Best Choice:
- Supabase - Postgres with real-time subscriptions
- Redis - Pub/sub for messaging
- WebSocket support
- Live updates
For Analytics
Best Choice:
- BigQuery - Serverless data warehouse
- Postgres with TimescaleDB - Time-series data
- Column-oriented storage
- Complex aggregations
For Caching
Best Choice:
- Redis - In-memory cache
- Upstash - Serverless Redis
- Extremely fast reads
- TTL support
Common Patterns
SQL with ORM (TypeScript)
// Prisma with Postgres
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const user = await prisma.user.create({
data: {
name: 'Alice',
email: '[email protected]',
posts: {
create: [
{ title: 'My first post', content: 'Hello World' },
],
},
},
include: {
posts: true,
},
});
NoSQL (MongoDB)
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.MONGODB_URI);
await client.connect();
const db = client.db('myapp');
const users = db.collection('users');
const user = await users.insertOne({
name: 'Alice',
email: '[email protected]',
createdAt: new Date(),
});
Key-Value (Redis)
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
// Set with expiration
await redis.set('session:123', JSON.stringify(userData), 'EX', 3600);
// Get
const data = await redis.get('session:123');
const user = JSON.parse(data);
Edge SQL (Turso)
import { createClient } from '@libsql/client';
const db = createClient({
url: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
});
const users = await db.execute('SELECT * FROM users WHERE email = ?', [email]);
Database Vendors by Use Case
Startup/Side Project (Low Cost)
- Supabase - Free tier, auth included, generous limits
- Neon - Free tier, serverless Postgres
- Turso - Free tier, edge database
- PlanetScale - Free tier, branching workflow
Production Application
- Supabase - $25/month, includes auth/storage
- Neon - Serverless Postgres, pay per use
- PlanetScale - Serverless MySQL, $29/month
- Amazon RDS - Full control, higher management overhead
Global/Multi-Region
- Turso - Edge replication, low latency
- CockroachDB - Distributed SQL
- Cloudflare D1 - SQLite at the edge
- MongoDB Atlas - Multi-region clusters
Analytics/Data Warehouse
- BigQuery - Pay per query, serverless
- Snowflake - Enterprise data warehouse
- Amazon Redshift - AWS data warehouse
- ClickHouse - Open-source OLAP
Database + Runtime Combinations
Node.js + Postgres
// Using Prisma ORM
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Or raw queries with pg
import pg from 'pg';
const client = new pg.Client(process.env.DATABASE_URL);
await client.connect();
Bun + SQLite
import { Database } from 'bun:sqlite';
const db = new Database('mydb.sqlite');
const query = db.prepare('SELECT * FROM users WHERE id = ?');
const user = query.get(userId);
Best Vendors: Local SQLite, Turso
Deno + Postgres
import { Client } from 'https://deno.land/x/postgres/mod.ts';
const client = new Client(Deno.env.get('DATABASE_URL'));
await client.connect();
Edge Runtime + Edge Database
// Cloudflare Workers + D1
export default {
async fetch(request, env) {
const result = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(userId).all();
return Response.json(result);
},
};
Best Vendors: Cloudflare D1, Turso
Security Best Practices
1. Use Environment Variables
// ✓ Good
const db = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
});
// ❌ Bad - hardcoded credentials
const db = new PrismaClient({
datasources: {
db: {
url: 'postgresql://user:password@host/db',
},
},
});
2. Parameterized Queries
// ✓ Good - prevents SQL injection
const user = await db.execute('SELECT * FROM users WHERE email = ?', [email]);
// ❌ Bad - vulnerable to SQL injection
const user = await db.execute(`SELECT * FROM users WHERE email = '${email}'`);
3. Connection Pooling
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20, // Maximum connections
idleTimeoutMillis: 30000,
});
// Reuse connections
const result = await pool.query('SELECT * FROM users');
4. Read-Only Replicas
// Write to primary
await primaryDb.execute('INSERT INTO users ...');
// Read from replica (lower load on primary)
const users = await replicaDb.execute('SELECT * FROM users');
Performance Optimization
Indexing
-- Create index on frequently queried columns
CREATE INDEX idx_users_email ON users(email);
-- Composite index for multiple columns
CREATE INDEX idx_posts_user_created ON posts(user_id, created_at);
Query Optimization
// ✓ Good - select only needed fields
const users = await prisma.user.findMany({
select: { id: true, name: true },
});
// ❌ Bad - selects everything
const users = await prisma.user.findMany();
Caching
// Layer 1: Application cache (Redis)
let user = await redis.get(`user:${id}`);
if (!user) {
// Layer 2: Database
user = await db.user.findUnique({ where: { id } });
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
}
Database Technologies
- PostgreSQL - Industry-standard relational database
- MongoDB - Popular NoSQL document database
- Firebase - Google's NoSQL with real-time and auth
- CockroachDB - Distributed SQL for global scale
- Redis - In-memory data structure store
- BigQuery - Google's serverless data warehouse
- Turso - Edge-hosted LibSQL database
- LibSQL - Open-source SQLite fork
Cloud Vendors
- Neon - Serverless Postgres with branching
- Cloudflare D1 - SQLite at the edge
- Cloudflare Hyperdrive - Database acceleration for edge workers
- Supabase - Postgres + Backend-as-a-Service
- PlanetScale - Serverless MySQL with branching
Key Takeaways
- PostgreSQL is the safest default choice for most applications
- NoSQL (MongoDB) for flexible schemas and rapid iteration
- Redis for caching and real-time features
- Edge databases (Turso, D1) for global low-latency apps
- BigQuery for analytics and data warehousing
- Choose serverless (Neon, PlanetScale, Supabase) for auto-scaling and lower costs
- Use ORMs (Prisma, Drizzle) for type safety with TypeScript
Related Topics
- Node.js - Popular runtime for database applications
- Bun - Fast runtime with built-in SQLite
- TypeScript - Type-safe database queries
- Next.js - Full-stack framework with database integration
- Serverless & Edge - Deploying with edge databases
The database you choose shapes your application's architecture, scalability, and performance. Start with PostgreSQL for most projects, consider edge databases for global applications, and use Redis for caching. Modern serverless providers like Neon and Supabase offer excellent developer experience with generous free tiers.