1---2name: cassandra3description: Design Cassandra tables, write efficient queries, and avoid distributed database pitfalls.4---5
6## Data Modeling Mistakes
7
8- Design tables around queries, not entities—denormalization is mandatory, not optional
9- One table per query pattern—Cassandra has no JOINs; duplicate data across tables
10- Partition key determines data distribution—all rows with same partition key on same node
11- Wide partitions kill performance—keep under 100MB; add time bucket to partition key if growing
12
13## Primary Key Traps
14
15- `PRIMARY KEY (a, b, c)`: `a` is partition key, `b` and `c` are clustering columns
16- `PRIMARY KEY ((a, b), c)`: `(a, b)` together is partition key—compound partition key
17- Clustering columns define sort order within partition—query must respect this order
18- Can't query by clustering column without partition key—unlike SQL indexes
19
20## Query Restrictions
21
22- `WHERE` must include full partition key—partial partition key fails unless `ALLOW FILTERING`
23- `ALLOW FILTERING` scans all nodes—never use in production; redesign table instead
24- Range queries only on last clustering column used—`WHERE a = ? AND b > ?` works, `WHERE a = ? AND c > ?` doesn't
25- `IN` on partition key hits multiple nodes—expensive; prefer single partition queries
26
27## Consistency Levels
28
29- `QUORUM` for most operations—majority of replicas; balances consistency and availability
30- `LOCAL_QUORUM` for multi-datacenter—avoids cross-DC latency
31- `ONE` for pure availability—may read stale data; fine for caches, bad for critical reads
32- Write + read consistency must overlap for strong consistency—`QUORUM` + `QUORUM` safe
33
34## Tombstones (Silent Performance Killer)
35
36- DELETE creates a tombstone, not actual deletion—tombstones persist until compaction
37- Mass deletes destroy read performance—thousands of tombstones scanned per query
38- TTL also creates tombstones—don't use short TTLs with high write volume
39- Check with `nodetool cfstats -H table`—`Tombstone` columns show problem
40
41## Batch Misuse
42
43- UNLOGGED BATCH is not faster—use only for atomic writes to same partition
44- LOGGED BATCH for multi-partition atomicity—adds coordination overhead
45- Don't batch unrelated writes—hurts coordinator; send individual async writes
46- Batch size limit ~50KB—larger batches fail or timeout
47
48## Anti-Patterns
49
50- Secondary indexes on high-cardinality columns—scatter-gather query, slow
51- Secondary indexes on frequently updated columns—creates tombstones
52- `SELECT *`—always list columns; schema changes break queries
53- UUID as partition key without time component—random distribution, hot spots during bulk loads
54
55## Lightweight Transactions
56
57- `IF NOT EXISTS` / `IF column = ?`—uses Paxos, 4x slower than normal write
58- Serial consistency for LWTs—`SERIAL` or `LOCAL_SERIAL`
59- Don't use for counters or high-frequency updates—contention kills throughput
60- Returns `[applied]` boolean—must check if operation succeeded
61
62## Collections and Counters
63
64- Sets/Lists/Maps stored with row—can't exceed 64KB, no pagination
65- List prepend is anti-pattern—creates tombstones; use append or Set
66- Counters require dedicated table—can't mix with regular columns
67- Counter increment is not idempotent—retry may double-count
68
69## Compaction Strategies
70
71- `SizeTieredCompactionStrategy` (default)—good for write-heavy, uses more disk space
72- `LeveledCompactionStrategy`—better read latency, higher write amplification
73- `TimeWindowCompactionStrategy`—for time-series with TTL; reduces tombstone overhead
74- Wrong strategy for workload = degraded performance over time
75
76## Operations
77
78- `nodetool repair` regularly—inconsistencies accumulate without repair
79- `nodetool status` shows cluster health—UN (Up Normal) is good, DN is down
80- Schema changes propagate eventually—wait for `nodetool describecluster` to show agreement
81- Rolling restarts: one node at a time, wait for UN status before next