视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
data-nosql-database【文档与办公】Use this skill when asked about MongoDB, Cassandra, DynamoDB, Couchbase, CosmosDB, NoSQL, document database, wide-column, key-value, consistency model, CAP theorem, sharding, or denormalization. This skill enforces: NoSQL type selection (document, key-value, wide-column, graph), MongoDB aggregation pipeline and indexing, Cassandra data modeling with …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Select and design NoSQL databases by access patterns, data shape, consistency requirements, and scale. Use document stores for flexible schemas, wide-column for high-scale writes, key-value for caching, and single-table designs for DynamoDB.
What is the primary access pattern?
├── Complex queries with flexible filters, aggregations
│ └── Document store (MongoDB, Couchbase)
├── Simple lookups by primary key, high throughput
│ ├── Key-value reads < 1KB → Redis (in-memory)
│ └── Larger payloads, durable → DynamoDB
├── High-volume writes, time-series data
│ └── Wide-column (Cassandra, Scylla, Bigtable)
├── Relationship-heavy traversals
│ └── Graph (Neo4j, Amazon Neptune)
What consistency model is required?
├── Strong consistency required → MongoDB (primary reads, majority write)
├── Tunable consistency → Cassandra (ONE/QUORUM/ALL per query)
├── Eventually consistent acceptable → DynamoDB (default eventual reads)
└── Strict serializable → Spanner, CosmosDB (Bounded Staleness)
What is the write volume?
├── < 10K writes/sec → MongoDB, DynamoDB, any
├── 10K-100K writes/sec → Cassandra, Scylla, DynamoDB (on-demand)
├── 100K-1M writes/sec → Scylla, Cassandra (tuned), Bigtable
└── > 1M writes/sec → Scylla, Bigtable, custom partitioning
What is the data size per entity?
├── Small documents (< 16MB) → MongoDB (16MB doc limit)
├── Large blobs → Store in S3/GCS, reference in NoSQL
└── Variable size → DynamoDB (400KB item limit)
What is the query pattern?
├── Always query by user/tenant ID
│ └── User/tenant ID as partition key
├── Query by time range within a partition
│ └── Partition: user/region, Sort/cluster: timestamp
├── Global queries across all partitions
│ └── GSI (DynamoDB), secondary index (MongoDB)
├── Need time-series + evenly distributed writes
│ └── Compound partition key with time bucket + hashed shard key
└── Need geographic data locality
└── Ranged shard key by region
Avoid:
├── Monotonically increasing keys (all writes to last shard)
├── Low-cardinality keys (jumbo partitions, hot spots)
├── Single-attribute keys for multi-tenant (all writes to one shard)
└── Frequently updated keys (cross-shard transactions)
Exact user phrases: "MongoDB", "Cassandra", "DynamoDB", "Couchbase", "CosmosDB", "NoSQL", "document database", "wide-column", "key-value", "consistency model", "CAP theorem", "sharding", "denormalization", "single-table design", "GSI", "LSI", "aggregation pipeline", "CQL".
Before activating, verify:
NoSQL data model with access patterns, sharding strategy, consistency configuration, and platform-specific DDL.
// MongoDB schema + indexes + aggregation
// Cassandra table DDL + compaction
// DynamoDB table config + GSI/LSI
# Consistency configuration
# Sharding strategy
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
300 lines of schema and configuration.
Document (MongoDB, Couchbase): nested data, flexible schema, complex queries. Wide-column (Cassandra, Scylla): high-volume writes, time-series, predictable queries by partition key. Key-value (Redis, DynamoDB): simple lookups, caching, session store. Graph (Neo4j): relationships are first-class. Decision matrix: write volume, query complexity, consistency needs, schema flexibility.
| Pattern | Read Latency | Write Throughput | Query Flexibility | Consistency |
|---|---|---|---|---|
| Document | Low | Medium | High | Tunable |
| Wide-column | Low | Very High | Low (by PK) | Tunable |
| Key-value | Very Low | Very High | Very Low | Configurable |
| Graph | Medium | Low | Very High (traversals) | Often strict |
Map all access patterns before designing schemas. For every query define: partition key, sort/clustering key, filter conditions, projected attributes, consistency requirement. DynamoDB: single-table design with entity type attribute and hierarchical keys. MongoDB: embed for contained sub-items, reference for shared entities. Cassandra: one table per query pattern.
// DynamoDB single-table: order + customer in one table
{
"PK": "CUST#123",
"SK": "ORDER#2025-03-15#ORD-001",
"entity_type": "order",
"customer_name": "Acme Corp",
"total": 250.00,
"status": "shipped",
"items": ["PROD-A", "PROD-B"],
"GSI1PK": "STATUS#shipped",
"GSI1SK": "2025-03-15"
}
MongoDB: shard key with high cardinality, low frequency, non-monotonic (hashed shard key for time-series). Cassandra: partition key distribution determines data placement; use compound partition keys for even distribution. DynamoDB: partition key hashed internally; use adaptive capacity for hot partitions. Avoid: monotonically increasing keys (all writes to one shard), low-cardinality keys (jumbo partitions).
// MongoDB shard key: hashed for even distribution
sh.shardCollection("shop.orders", { "order_id": "hashed" })
// MongoDB shard key: ranged for geographic queries
sh.shardCollection("analytics.events", { "region": 1, "timestamp": -1 })
// Cassandra compound partition key with clustering
CREATE TABLE orders_by_customer (
customer_id TEXT,
order_month TEXT,
order_id TIMEUUID,
total DECIMAL,
status TEXT,
PRIMARY KEY ((customer_id, order_month), order_id)
) WITH CLUSTERING ORDER BY (order_id DESC);
MongoDB: single-field, compound, multikey (arrays), text, geospatial, hashed. Use partial indexes to reduce index size. DynamoDB GSI: alternative partition key, eventually consistent by default, projected attributes control cost. LSI: same partition key, different sort key, strongly consistent, 5 per table. Cassandra secondary indexes: local (per node) for low-cardinality columns; SASI (deprecated) for full-text. Prefer materialized views over indexes in Cassandra.
{
"TableName": "orders",
"KeySchema": [
{ "AttributeName": "customer_id", "KeyType": "HASH" },
{ "AttributeName": "order_date", "KeyType": "RANGE" }
],
"GlobalSecondaryIndexes": [{
"IndexName": "GSI-Status-Date",
"KeySchema": [
{ "AttributeName": "status", "KeyType": "HASH" },
{ "AttributeName": "shipped_date", "KeyType": "RANGE" }
],
"Projection": { "ProjectionType": "INCLUDE", "NonKeyAttributes": ["total"] }
}]
}
CAP trade-off: partition tolerance is mandatory (P), choose consistency (CP) or availability (AP). MongoDB: primary reads (strong), secondary reads (eventual), majority write concern. Cassandra: ONE (high availability), QUORUM (balanced), ALL (strong). DynamoDB: eventually consistent reads (default), strongly consistent reads (1 WCU headroom). Use quorum-based reads for critical data, eventual for dashboards.
# MongoDB write concern
writeConcern:
w: majority
j: true
wtimeout: 5000
# Cassandra consistency per query
SELECT * FROM orders WHERE customer_id = '123'
USING CONSISTENCY LOCAL_QUORUM;
Computed fields: store aggregates (order count, total spent) to avoid joins. Complex attributes: embed line items in orders, comments in posts. Cross-entity data: duplicate customer name in each order for fast listing. Pre-joined data: create materialized join tables. Path enumeration: store full category path. Pre-joined data eliminates read-time joins at the cost of write-time complexity.
// MongoDB embedded items
{
"_id": "order:123",
"customer": { "id": "cust:456", "name": "Acme", "email": "acme@co" },
"items": [
{ "product_id": "p:1", "name": "Widget", "qty": 2, "price": 10.00 }
],
"total": 20.00
}
MongoDB aggregation pipeline stages: $match (filter early), $project (shape documents), $group (group by key), $sort (order results), $limit/$skip (pagination), $unwind (deconstruct arrays), $lookup (join across collections), $bucket (histogram), $facet (multi-faceted aggregation). Performance: use indexes for $match and $sort stages; $lookup requires index on foreign collection; avoid $unwind on large arrays; use allowDiskUse for memory-intensive pipelines. Use $merge to output aggregation results to a new collection.
// Order analytics with facet
db.orders.aggregate([
{ $match: { created_at: { $gte: ISODate("2025-01-01") } } },
{ $facet: {
by_status: [
{ $group: { _id: "$status", count: { $sum: 1 }, total: { $sum: "$total" } } }
],
by_region: [
{ $lookup: { from: "customers", localField: "customer_id", foreignField: "_id", as: "customer" } },
{ $unwind: "$customer" },
{ $group: { _id: "$customer.region", count: { $sum: 1 }, revenue: { $sum: "$total" } } }
],
daily_trend: [
{ $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$created_at" } }, count: { $sum: 1 } } },
{ $sort: { _id: 1 } }
]
} }
]);
MongoDB: mongodump for logical backups (slower, cross-version), file-system snapshots for fast physical backups (EBS snapshots, LVM), Ops Manager for continuous backup with point-in-time recovery. Cassandra: nodetool snapshot for hard-link snapshots, incremental backups with incremental_backups=true, commit log archiving for point-in-time recovery. DynamoDB: on-demand backup (full copy), point-in-time recovery (PITR) for last 35 days, cross-region replication for DR.
# Cassandra backup configuration
incremental_backups: true
commitlog_archiving:
properties_dir: /etc/cassandra/commitlog_archiving.properties
archive_command: "cp %path /backup/commitlog/%name"
restore_command: "cp /backup/commitlog/%name %path"
MongoDB: SCRAM-SHA-256 authentication, x.509 certificate auth, LDAP/Kerberos integration, field-level encryption, audit logging. Cassandra: role-based access control with CQL GRANT/REVOKE, mTLS for inter-node encryption, system_auth keyspace replication across all datacenters. DynamoDB: IAM policies for table-level access, VPC endpoints for network isolation, KMS encryption at rest, DAX encryption in transit.
-- Cassandra RBAC
CREATE ROLE app_user WITH PASSWORD = 'secure_password' AND LOGIN = true;
GRANT SELECT ON KEYSPACE shop TO app_user;
GRANT MODIFY ON TABLE shop.orders TO app_user;
MongoDB: bulk writes, ordered=false for best-effort, journaled writes. Cassandra: compaction strategy determines write amplification (STCS for write-heavy, LCS for read-heavy, TWCS for time-series). DynamoDB: provisioned capacity with auto-scaling, burst capacity for spikes. Write isolation: avoid read-before-write patterns (conditional updates in DynamoDB, upserts in Cassandra).
// Cassandra compaction: TimeWindowCompactionStrategy for time-series
CREATE TABLE sensor_readings (
sensor_id TEXT,
day TEXT,
ts TIMESTAMP,
value DOUBLE,
PRIMARY KEY ((sensor_id, day), ts)
) WITH CLUSTERING ORDER BY (ts DESC)
AND compaction = {
'class': 'TimeWindowCompactionStrategy',
'compaction_window_size': 1,
'compaction_window_unit': 'DAYS'
};
Designing normalized schemas with foreign keys and expecting joins. NoSQL requires denormalization and embedding. MongoDB supports $lookup but it's slow. DynamoDB has no joins. Cassandra has no joins.
Using monotonically increasing keys (timestamps, auto-increment IDs) as shard keys. All writes go to the last shard, creating a hot spot. Use hashed shard keys for time-series data.
Secondary indexes in wide-column stores (Cassandra SASI, MongoDB slow queries) are often slower than full scans. Prefer query-by-design (one table per access pattern in Cassandra, GSIs in DynamoDB).
MongoDB has a 16MB document limit. DynamoDB has a 400KB item limit. Exceeding these causes write failures. Plan for large items (gridFS for MongoDB, S3 references for DynamoDB).
Cassandra WHERE clauses can only filter on partition key + clustering columns. Any non-key filter requires ALLOW FILTERING (full scan). Design tables per query pattern.
Using on-demand capacity for predictable workloads costs significantly more. Provisioned capacity with auto-scaling reduces costs 50-70%.
Queries without indexes cause collection scans, blocking reads on large collections. Always index query fields. Use explain() to verify index usage.
Creating separate tables per entity type loses the single-table design benefits. Use composite keys (PK/SK) with entity_type attribute for multi-entity access.
Default compaction (SizeTieredCompactionStrategy) causes write amplification and disk space bloat. Use TimeWindowCompactionStrategy for time-series, LeveledCompactionStrategy for read-heavy.
Using different consistency levels for read and write without understanding the implications. Write concern w:majority with read concern local can read uncommitted data.
MongoDB offers richer queries (aggregation pipeline, text search, geospatial) with flexible schema. DynamoDB offers single-digit-millisecond latency at any scale with auto-scaling. Choose MongoDB for complex querying. Choose DynamoDB for predictable key-value access with auto-scaling.
Cassandra writes are faster and scale linearly with nodes. MongoDB reads are more flexible (any field, any filter). Cassandra has no joins, no aggregations, no secondary indexes (in practice). MongoDB has full query support. Choose Cassandra for write-heavy, no-compromise scalability. Choose MongoDB for developer productivity.
DynamoDB is fully managed with auto-scaling, no ops overhead. Cassandra requires operational expertise (compaction, repairs, gossip management). DynamoDB has 400KB item limit, 1MB query limit, and no joins. Cassandra has 2GB cell limit but no practical query size limit. Choose DynamoDB for managed simplicity. Choose Cassandra for multi-region, multi-datacenter control.
Document stores: flexible schema, rich queries, medium scale. Wide-column: rigid schema by partition key, massive scale, time-series. Key-value: simplest model, fastest lookups, caching. Choose document for general purpose. Choose wide-column for write-heavy time-series. Choose key-value for caching and session management.
Data access pattern?
├── Key-value lookups by primary key
│ ├── High throughput, low latency (< 5ms)
│ │ └── DynamoDB or Redis
│ └── Simple caching, session management
│ └── Redis (in-memory, TTL-based expiry)
├── Document-oriented, flexible schema
│ ├── Rich queries, aggregations, indexes
│ │ └── MongoDB (flexible schema, secondary indexes)
│ └── Embedded sub-documents, hierarchical data
│ └── MongoDB (embedding avoids joins)
├── Wide-column, time-series, massive write throughput
│ ├── Time-series event data
│ │ └── Cassandra (partition by time bucket, cluster by entity)
│ └── IoT sensor data, write-heavy workloads
│ └── Cassandra (linear scale, no single point of contention)
├── Graph, relationship-heavy
│ ├── Social network, recommendation engine
│ │ └── Neo4j (property graph model, traversal queries)
│ └── Fraud detection, network analysis
│ └── Neptune or Neo4j
└── Search, full-text
└── Elasticsearch (inverted index, relevance scoring)
# Single-table design for e-commerce
# PK: entity type + ID, SK: relationship/sort key
items = {
# Customer entity
{"PK": "CUSTOMER#123", "SK": "METADATA", "name": "Alice", "email": "alice@org.com", "tier": "gold"},
# Customer's orders
{"PK": "CUSTOMER#123", "SK": "ORDER#2026-05-01#ORD001", "order_total": 150.00, "status": "shipped"},
{"PK": "CUSTOMER#123", "SK": "ORDER#2026-05-15#ORD002", "order_total": 75.00, "status": "pending"},
# Customer's addresses
{"PK": "CUSTOMER#123", "SK": "ADDR#HOME", "street": "123 Main St", "city": "Portland"},
# Order entity (GSI for order lookup)
{"PK": "ORDER#ORD001", "SK": "METADATA", "customer_id": "123", "total": 150.00, "status": "shipped"},
{"PK": "ORDER#ORD001", "SK": "ITEM#PROD-A", "product": "Widget", "price": 100.00, "qty": 1},
{"PK": "ORDER#ORD001", "SK": "ITEM#PROD-B", "product": "Gadget", "price": 50.00, "qty": 1},
}
# Access patterns:
# Get customer + all orders: Query(PK="CUSTOMER#123")
# Get customer orders by date: Query(PK="CUSTOMER#123", SK begins_with("ORDER#2026-05"))
# Get order details: Query(PK="ORDER#ORD001")
# GSI on status for all orders by status
How is the data accessed?
├── Sub-document accessed WITH parent (always together)
│ └── Embed (e.g., order items in order document)
├── Sub-document independent, but small cardinality
│ └── Embed (e.g., addresses in customer document)
├── Sub-document independent, large cardinality
│ └── Reference with DBRef or manual ID (e.g., orders per customer)
├── Many-to-many relationships
│ └── Reference array (e.g., product categories)
└── Growing unbounded array
└── Reference (e.g., customer activity log → separate collection)
cassandra_modeling:
rule: "One table per query pattern"
example:
query_pattern_1: "Get orders by customer_id ordered by order_date DESC"
table: |
CREATE TABLE orders_by_customer (
customer_id TEXT,
order_date DATE,
order_id UUID,
total DECIMAL,
status TEXT,
PRIMARY KEY (customer_id, order_date, order_id)
) WITH CLUSTERING ORDER BY (order_date DESC, order_id ASC);
query_pattern_2: "Get orders by status and date range"
table: |
CREATE TABLE orders_by_status (
status TEXT,
order_date DATE,
customer_id TEXT,
order_id UUID,
total DECIMAL,
PRIMARY KEY ((status, order_date), customer_id, order_id)
);
denormalization:
- "Duplicate data across tables — disk is cheap, joins are impossible"
- "Update in batch when source data changes"
- "Use Materialized Views for automatic denormalization (limited)"
data-graph-database for relationship-heavy queries
data-search-engine for full-text search over NoSQL data