Skip to main content

🗄️ Database Internals

"The database is the heart of any application."

Understanding database internals helps you write efficient queries, choose the right data model, and optimize performance under load.


🔍 MySQL Indexing

Index Types

TypeDescriptionUse Case
B+ TreeBalanced tree, range queriesPrimary keys, most columns
HashO(1) lookupExact match only
Full-TextText searchDocument search
CompositeMulti-columnMulti-condition queries

Index Optimization Rules

-- ✅ Good: Index can be fully utilized
SELECT * FROM users WHERE status = 'active' AND created_at > '2024-01-01';
-- Index: (status, created_at)

-- ❌ Bad: Index cannot help with leading wildcard
SELECT * FROM users WHERE name LIKE '%john%';

-- ✅ Good: Covering index (no table lookup)
SELECT id, name FROM users WHERE status = 'active';
-- Index: (status, id, name) -- includes all needed columns

Query Analysis

EXPLAIN SELECT * FROM orders 
WHERE user_id = 100 AND status = 'pending'
ORDER BY created_at DESC;
ColumnWhat to Check
typeShould be ref, eq_ref or range, not ALL
keyIndex being used
rowsEstimated rows scanned (lower is better)
ExtraWatch for Using filesort, Using temporary

🔐 Transaction Isolation Levels

LevelDirty ReadNon-RepeatablePhantom ReadPerformance
Read UncommittedFastest
Read CommittedFast
Repeatable Read✓*Medium
SerializableSlowest

*MySQL InnoDB prevents phantom reads with gap locking


⚡ Redis Caching

Data Structures

StructureUse CaseCommands
StringSimple cache, countersGET, SET, INCR
HashObject storageHGET, HSET, HMGET
ListMessage queues, feedsLPUSH, RPOP, LRANGE
SetUnique itemsSADD, SMEMBERS, SINTER
Sorted SetLeaderboards, timelinesZADD, ZRANGE, ZRANK

Caching Patterns

// Cache-Aside Pattern
public User getUser(Long id) {
String key = "user:" + id;

// 1. Check cache
User cached = redis.get(key);
if (cached != null) return cached;

// 2. Cache miss - fetch from DB
User user = userRepository.findById(id);

// 3. Store in cache with TTL
redis.setex(key, 3600, user);

return user;
}

Cache Invalidation Strategies

StrategyDescriptionConsistency
TTLExpire after timeEventual
Write-throughUpdate cache on writeStrong
Event-drivenInvalidate on eventsNear real-time
Version keysAppend version to keyStrong

Persistence Options

ModeDescriptionTrade-off
RDBPoint-in-time snapshotsFaster recovery, data loss window
AOFAppend-only logMinimal data loss, larger files
RDB + AOFCombined approachBest durability

📝 Detailed Topics


Production Tips
  1. Always use connection pooling (HikariCP for Java)
  2. Add indexes based on query patterns, not guesses
  3. Monitor slow query logs regularly
  4. Set appropriate TTLs for cache entries
  5. Use read replicas for read-heavy workloads