✏️ Explanatory Question
Level: Very Hard — The ultimate scaling question; the shard-key choice is a near-irreversible decision that makes or breaks the system.
orders table has grown to 5 billion rows and 4 TB. A single MySQL server can't handle the write throughput or storage anymore — even with replicas (which only scale reads). The interviewer asks: "How do you scale writes? Walk me through sharding, how you'd pick the shard key, and what breaks."
Sharding = horizontal partitioning across multiple servers. Each shard holds a subset of the rows. Unlike replication (which copies all data to scale reads), sharding splits data to scale writes and storage.
| Strategy | How | Weakness |
|---|---|---|
| Range-based | Shard by id/date ranges (1–1M → shard A) | Hotspots (newest shard gets all writes) |
| Hash-based | hash(shard_key) % N |
Re-sharding requires rehashing everything |
| Directory/lookup | A lookup table maps key → shard | Lookup service is a bottleneck/SPOF |
| Consistent hashing | Hash ring; adding nodes moves minimal data | More complex to implement |
A good shard key must satisfy three properties:
-- Shard key = customer_id, hashed across 4 shards
-- shard_number = customer_id % 4
-- Customer 1001 -> 1001 % 4 = 1 -> Shard 1
-- All of a customer's orders live on ONE shard (great locality)
-- Query for one customer -> single shard, fast:
-- (routed by app/proxy to Shard 1)
SELECT * FROM orders WHERE customer_id = 1001;
-- PROBLEM query -> "all orders today" must hit ALL shards (scatter-gather):
-- SELECT * FROM orders WHERE order_date = CURDATE(); -- fan-out to every shard
order_id instead would scatter a customer's orders across shards, making their order history a cross-shard query. Shard by the dominant access pattern's key.
| Problem | Why It's Hard |
|---|---|
| Cross-shard JOINs | Can't JOIN across servers; must gather in app or denormalize |
| Cross-shard transactions | No single ACID transaction; need 2-phase commit or sagas |
| Unique IDs | AUTO_INCREMENT collides across shards; need UUID/Snowflake |
| Aggregations | "Total revenue" must query every shard and merge |
| Re-sharding | Adding shards means migrating data live — very risky |
| Hotspots | A "celebrity" key can overload one shard |
-- AUTO_INCREMENT would collide (each shard starts at 1). Options:
-- Option A: interleaved auto-increment (offset per shard)
-- Shard 0: 1,5,9... Shard 1: 2,6,10... (auto_increment_increment=4)
SET @@auto_increment_increment = 4; -- number of shards
SET @@auto_increment_offset = 1; -- this shard's offset
-- Option B (preferred): globally-unique time-sortable IDs (Snowflake)
-- 64-bit: [timestamp][shard/machine id][sequence] -> unique & ordered