Document Stores
Document stores store data as flexible, JSON-like documents.
Document Store Concepts
Document: Self-contained unit of data
Collection: Group of documents (like table)
Database: Group of collections
Document:
{
"_id": "user123",
"name": "Alice",
"email": "alice@example.com",
"address": {
"street": "123 Main St",
"city": "New York"
},
"hobbies": ["reading", "hiking"]
}
MongoDB Example
// Insert
db.users.insertOne({
name: "Alice",
email: "alice@example.com",
address: { street: "123 Main St", city: "NYC" }
});
// Query
db.users.find({ "address.city": "NYC" });
// Update
db.users.updateOne(
{ _id: ObjectId("...") },
{ $set: { "address.city": "Boston" } }
);
// Aggregation
db.orders.aggregate([
{ $group: { _id: "$userId", total: { $sum: "$amount" } } }
]);
Document Store Use Cases
| Use Case | Why |
|---|---|
| Content management | Flexible schemas |
| User profiles | Varying attributes |
| Product catalogs | Different product types |
| Logging | Semi-structured data |
| Real-time analytics | Fast writes |
MongoDB Features
- Rich query language
- Indexing (single, compound, text)
- Aggregation framework
- Replication ( Replica Sets)
- Sharding
- ACID transactions (since 4.0)
When to Use Document Stores
Use when:
- Data is semi-structured
- Schema changes frequently
- Need fast reads/writes
- Flexible querying needed
- Horizontal scaling required
Avoid when:
- Complex joins required
- Strong ACID needed
- Data is highly relational
Key-Value Stores
Key-value stores are the simplest NoSQL databases.
Key-Value Concepts
Key: Unique identifier
Value: Any data (string, JSON, binary)
Operations:
- GET(key) → value
- PUT(key, value)
- DELETE(key)
Redis Example
-- Strings
SET user:123:name "Alice"
GET user:123:name
-- Hashes
HSET user:123 name "Alice" email "a@b.com"
HGET user:123 name
-- Lists
LPUSH notifications "msg1" "msg2"
RPOP notifications
-- Sets
SADD friends:user123 "user456" "user789"
SMEMBERS friends:user123
-- Sorted Sets
ZADD leaderboard 100 "player1" 200 "player2"
ZREVRANGE leaderboard 0 9
Key-Value Store Use Cases
| Use Case | Example |
|---|---|
| Session storage | User sessions |
| Caching | API responses |
| User profiles | Quick lookups |
| Shopping carts | Real-time data |
| Leaderboards | Sorted sets |
| Rate limiting | Counter increments |
Redis vs Memcached
| Aspect | Redis | Memcached |
|---|---|---|
| Data types | Multiple | Strings only |
| Persistence | Yes | No |
| Replication | Yes | No |
| Clustering | Yes | Yes |
| Use case | Complex state | Simple caching |
When to Use Key-Value
Use when:
- Simple data model
- High throughput needed
- Low latency critical
- Data fits in memory
Avoid when:
- Complex queries needed
- Data larger than memory
- Complex relationships
Column-Family Stores
Column-family stores organize data by columns, not rows.
Column-Family Concepts
Row Key: Unique identifier
Column Family: Group of columns
Column: Name-value pair
Row Key → Column Family → Column → Value
Example:
user:123 →
personal: name=Alice, email=a@b.com
activity: last_login=2024-01-15, login_count=42
Cassandra Example
-- Create table
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT,
created_at TIMESTAMP
);
-- Insert
INSERT INTO users (user_id, name, email)
VALUES (uuid(), 'Alice', 'alice@example.com');
-- Query (must use partition key)
SELECT * FROM users WHERE user_id = ?;
-- Query by secondary index
SELECT * FROM users WHERE email = 'alice@example.com';
Cassandra Features
- High write throughput
- Linear horizontal scaling
- Tunable consistency
- No single point of failure
- CQL (SQL-like query language)
- Time-series optimized
Column-Family Use Cases
| Use Case | Why |
|---|---|
| Time-series data | Optimized for time-based writes |
| IoT data | High write throughput |
| Event logging | Append-heavy workloads |
| Recommendation engine | Fast reads |
| Messaging | High availability |
When to Use Column-Family
Use when:
- Write-heavy workloads
- High availability needed
- Time-series data
- Linear scalability required
Avoid when:
- Complex joins needed
- ACID transactions required
- Read-heavy with complex queries
Graph Databases
Graph databases store data as nodes and relationships.
Graph Concepts
Nodes: Entities (users, products)
Relationships: Connections between nodes
Properties: Attributes on nodes/relationships
Example:
(Alice)──FOLLOWS──→(Bob)
│ │
│ │
LIKES LIKES
│ │
▼ ▼
(Post1) (Post2)
Neo4j Example
// Create nodes
CREATE (alice:Person {name: 'Alice', age: 25})
CREATE (bob:Person {name: 'Bob', age: 30})
// Create relationship
CREATE (alice)-[:FOLLOWS]->(bob)
CREATE (alice)-[:LIKES]->(post1)
// Query: Friends of friends
MATCH (me:Person {name: 'Alice'})-[:FOLLOWS]->(friend)-[:FOLLOWS]->(fof)
WHERE NOT (me)-[:FOLLOWS]->(fof) AND me <> fof
RETURN fof.name
// Query: Shortest path
MATCH path = shortestPath(
(alice:Person {name: 'Alice'})-[*]-(charlie:Person {name: 'Charlie'})
)
RETURN path
Graph Database Use Cases
| Use Case | Why |
|---|---|
| Social networks | Relationship queries |
| Recommendation engines | Similar items, friends |
| Fraud detection | Pattern matching |
| Knowledge graphs | Connected data |
| Network/IT ops | Dependency mapping |
When to Use Graph Databases
Use when:
- Data has many relationships
- Relationship queries are common
- Path finding needed
- Pattern matching required
Avoid when:
- Data is tabular
- Simple CRUD operations
- High write throughput needed
Practice Problems
Design a scalable NoSQL Databases system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale NoSQL Databases to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for NoSQL Databases and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. What is a document store?
2. When should you use a key-value store?
3. What is the main advantage of column-family stores?
4. When should you use a graph database?
Flashcards
Question
What are the 4 main NoSQL database types?
Click to reveal answer
Answer
1) Document stores (MongoDB), 2) Key-value stores (Redis), 3) Column-family (Cassandra), 4) Graph databases (Neo4j).
Question
When should you use a document store?
Click to reveal answer
Answer
When data is semi-structured, schema changes frequently, need fast reads/writes, flexible querying, and horizontal scaling.
Question
What is the difference between Redis and Memcached?
Click to reveal answer
Answer
Redis supports multiple data types, persistence, replication. Memcached is simpler, strings only, no persistence. Redis for complex state, Memcached for simple caching.
Question
When should you use a graph database?
Click to reveal answer
Answer
When data has many relationships, relationship queries are common, need path finding or pattern matching. Examples: social networks, recommendations.
Question
What is NoSQL Databases?
Click to reveal answer
Answer
NoSQL Databases is a key concept in system design.
Revision Notes
Key Takeaways
- 1.NoSQL databases optimize for specific use cases
- 2.Document stores for flexible, semi-structured data
- 3.Key-value stores for simple, high-throughput data
- 4.Column-family for write-heavy, time-series workloads
- 5.Graph databases for relationship-heavy data
Interview Tips
- •Choose NoSQL type based on data model and access patterns
- •Discuss tradeoffs vs SQL for each NoSQL type
- •Mention specific tools (MongoDB, Redis, Cassandra, Neo4j)
- •Consider consistency requirements when choosing NoSQL
Cheat Sheet
NoSQL Databases - Cheat Sheet
4 Types:
- Document (MongoDB)
- Flexible JSON-like documents
- Use: CMS, user profiles, catalogs
- Key-Value (Redis)
- Simple key-value pairs
- Use: Sessions, caching, leaderboards
- Column-Family (Cassandra)
- Data organized by columns
- Use: Time-series, IoT, logging
- Graph (Neo4j)
- Nodes and relationships
- Use: Social networks, recommendations
Choose NoSQL When:
- Flexible schema needed
- High write throughput
- Horizontal scaling required
- Simple data model
- Eventual consistency acceptable