nosql-database-design
About
This Claude Skill designs NoSQL database schemas for MongoDB and DynamoDB, helping developers model document structures and plan data architectures. It covers data modeling patterns, denormalization strategies, and query optimization for both document and key-value databases. Use it when designing collections, making embedding vs. referencing decisions, or optimizing NoSQL indexing strategies.
Documentation
NoSQL Database Design
Overview
Design scalable NoSQL schemas for MongoDB (document) and DynamoDB (key-value). Covers data modeling patterns, denormalization strategies, and query optimization for NoSQL systems.
When to Use
- MongoDB collection design
- DynamoDB table and index design
- Document structure modeling
- Embedding vs. referencing decisions
- Query pattern optimization
- NoSQL indexing strategies
- Data denormalization planning
MongoDB Schema Design
Document Structure Design
MongoDB - Embedded Documents:
// Single document with embedded arrays
db.createCollection("users")
db.users.insertOne({
_id: ObjectId("..."),
email: "[email protected]",
name: "John Doe",
createdAt: new Date(),
// Embedded address
address: {
street: "123 Main St",
city: "New York",
state: "NY",
zipCode: "10001"
},
// Embedded array of items
orders: [
{
orderId: ObjectId("..."),
date: new Date(),
total: 149.99
},
{
orderId: ObjectId("..."),
date: new Date(),
total: 89.99
}
]
})
MongoDB - Referenced Documents:
// Separate collections with references
db.createCollection("users")
db.createCollection("orders")
db.users.insertOne({
_id: ObjectId("..."),
email: "[email protected]",
name: "John Doe"
})
db.orders.insertMany([
{
_id: ObjectId("..."),
userId: ObjectId("..."), // Reference to user
orderDate: new Date(),
total: 149.99
},
{
_id: ObjectId("..."),
userId: ObjectId("..."),
orderDate: new Date(),
total: 89.99
}
])
// Query with $lookup for JOINs
db.orders.aggregate([
{
$match: { userId: ObjectId("...") }
},
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
}
])
Indexing in MongoDB
// Single field index
db.users.createIndex({ email: 1 })
db.orders.createIndex({ createdAt: -1 })
// Compound index
db.orders.createIndex({ userId: 1, createdAt: -1 })
// Text index for search
db.products.createIndex({ name: "text", description: "text" })
// Geospatial index
db.stores.createIndex({ location: "2dsphere" })
// TTL index for auto-expiration
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
// Sparse index (only documents with field)
db.users.createIndex({ phone: 1 }, { sparse: true })
// Check index usage
db.users.aggregate([{ $indexStats: {} }])
Schema Validation
// Define collection validation schema
db.createCollection("products", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "price", "category"],
properties: {
_id: { bsonType: "objectId" },
name: {
bsonType: "string",
description: "Product name (required)"
},
price: {
bsonType: "decimal",
minimum: 0,
description: "Price must be positive"
},
category: {
enum: ["electronics", "clothing", "food"],
description: "Category must be one of listed values"
},
tags: {
bsonType: "array",
items: { bsonType: "string" }
},
createdAt: {
bsonType: "date"
}
}
}
}
})
DynamoDB Schema Design
Table Structure
// DynamoDB table with single primary key
const TableName = "users"
const params = {
TableName,
KeySchema: [
{ AttributeName: "userId", KeyType: "HASH" } // Partition key
],
AttributeDefinitions: [
{ AttributeName: "userId", AttributeType: "S" } // String
],
BillingMode: "PAY_PER_REQUEST" // On-demand
}
// DynamoDB table with composite primary key
const ordersParams = {
TableName: "orders",
KeySchema: [
{ AttributeName: "userId", KeyType: "HASH" }, // Partition key
{ AttributeName: "orderId", KeyType: "RANGE" } // Sort key
],
AttributeDefinitions: [
{ AttributeName: "userId", AttributeType: "S" },
{ AttributeName: "orderId", AttributeType: "S" }
],
BillingMode: "PAY_PER_REQUEST"
}
Global Secondary Indexes (GSI)
// Add GSI for querying by email
const gsiParams = {
TableName: "users",
AttributeDefinitions: [
{ AttributeName: "email", AttributeType: "S" }
],
GlobalSecondaryIndexes: [
{
IndexName: "emailIndex",
KeySchema: [
{ AttributeName: "email", KeyType: "HASH" }
],
Projection: {
ProjectionType: "ALL" // Return all attributes
},
BillingMode: "PAY_PER_REQUEST"
}
]
}
// GSI with composite key for time-based queries
const timeIndexParams = {
GlobalSecondaryIndexes: [
{
IndexName: "userCreatedIndex",
KeySchema: [
{ AttributeName: "userId", KeyType: "HASH" },
{ AttributeName: "createdAt", KeyType: "RANGE" }
],
Projection: { ProjectionType: "ALL" },
BillingMode: "PAY_PER_REQUEST"
}
]
}
DynamoDB Item Operations
// Put item (insert/update)
const putParams = {
TableName: "users",
Item: {
userId: { S: "user-123" },
email: { S: "[email protected]" },
name: { S: "John Doe" },
createdAt: { N: Date.now().toString() },
metadata: {
M: {
joinDate: { N: Date.now().toString() },
source: { S: "web" }
}
}
}
}
// Query using GSI
const queryParams = {
TableName: "users",
IndexName: "emailIndex",
KeyConditionExpression: "email = :email",
ExpressionAttributeValues: {
":email": { S: "[email protected]" }
}
}
// Batch get items
const batchGetParams = {
RequestItems: {
"users": {
Keys: [
{ userId: { S: "user-123" } },
{ userId: { S: "user-456" } }
]
}
}
}
Denormalization Patterns
MongoDB - Embedding for Performance:
// Embed frequently accessed data to avoid lookups
db.orders.insertOne({
_id: ObjectId("..."),
userId: ObjectId("..."),
userEmail: "[email protected]", // Denormalized
userName: "John Doe", // Denormalized
createdAt: new Date(),
items: [
{
productId: ObjectId("..."),
productName: "Laptop", // Denormalized
productPrice: 999.99, // Denormalized
quantity: 1
}
]
})
DynamoDB - Denormalization with Consistency:
// Store related data in same item to ensure consistency
const params = {
TableName: "orders",
Item: {
userId: { S: "user-123" },
orderId: { S: "order-456" },
orderDate: { N: Date.now().toString() },
// User data snapshot at order time
userSnapshot: {
M: {
email: { S: "[email protected]" },
address: { S: "123 Main St" }
}
},
// Items with product information
items: {
L: [
{
M: {
productId: { S: "prod-789" },
name: { S: "Laptop" },
price: { N: "999.99" },
quantity: { N: "1" }
}
}
]
}
}
}
Design Patterns
MongoDB - Time-Series Pattern:
// Efficient time-series data storage
db.sensor_data.insertOne({
_id: ObjectId("..."),
sensorId: "sensor-123",
date: ISODate("2024-01-15"),
measurements: [
{ time: "12:00", temperature: 72.5, humidity: 45 },
{ time: "12:01", temperature: 72.6, humidity: 45.2 },
{ time: "12:02", temperature: 72.4, humidity: 44.8 }
]
})
// Index for efficient queries
db.sensor_data.createIndex({ sensorId: 1, date: -1 })
DynamoDB - One-to-Many Relationship:
// Store one-to-many relationships efficiently
// User comments using userId as partition key, commentId as sort key
const commentParams = {
TableName: "comments",
Item: {
userId: { S: "user-123" }, // Partition key
commentId: { S: "comment-789" }, // Sort key
postId: { S: "post-456" },
content: { S: "Great article!" },
createdAt: { N: Date.now().toString() }
}
}
Capacity Planning
MongoDB - Horizontal Scaling:
// Sharding for large collections
sh.shardCollection("ecommerce.orders", { userId: "hashed" })
// Monitor shard distribution
db.orders.aggregate([
{ $group: { _id: "$userId", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
DynamoDB - Partition Key Design:
// Good: Distribute across many keys
// Partition key: "USER#123" (spreads across partitions)
// Sort key: "ORDER#2024-01"
// Bad: Hot partition
// Partition key: "ADMIN" (all admin operations hit same partition)
// Solution: Add timestamp or random suffix
// Partition key: "ADMIN#20240115#random"
Migration Considerations
- Plan data migration strategy
- Consider consistency requirements
- Test query patterns before finalizing schema
- Monitor performance after deployment
- Document relationships and access patterns
- Plan for schema evolution
Resources
Quick Install
/plugin add https://github.com/aj-geddes/useful-ai-prompts/tree/main/nosql-database-designCopy and paste this command in Claude Code to install this skill
GitHub 仓库
Related Skills
langchain
MetaLangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.
Algorithmic Art Generation
MetaThis skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.
webapp-testing
TestingThis Claude Skill provides a Playwright-based toolkit for testing local web applications through Python scripts. It enables frontend verification, UI debugging, screenshot capture, and log viewing while managing server lifecycles. Use it for browser automation tasks but run scripts directly rather than reading their source code to avoid context pollution.
requesting-code-review
DesignThis skill dispatches a code-reviewer subagent to analyze code changes against requirements before proceeding. It should be used after completing tasks, implementing major features, or before merging to main. The review helps catch issues early by comparing the current implementation with the original plan.
