Why split a table
A shop keeps every order in one table on one server. As it grows, every write lands on that one machine until it runs out of disk and speed. Replicas (copies) can share the reads, but not the writes.
Sharding splits a table’s rows across several servers, called shards. A rule picks each row’s shard from one column, the shard key. Here the key is customer_id and the rule is key % 3: the remainder after dividing by 3.
Customer 7: 7 % 3 = 1, so shard 1. Customer 12: shard 0. Customer 5: shard 2. Every shard has the same columns but holds only its own rows, and no row is on two shards.
Asking a sharded table
The app wants customer 7’s orders: SELECT * FROM orders WHERE customer_id = 7. It sends the query to the router, the part that knows the rule and where every shard is.
The query names the shard key, so the router runs the rule itself: 7 % 3 = 1. It sends the query to shard 1 only. The other shards never hear about it.
Shard 1 searches only its own 2 rows, finds customer 7’s order (total 30) and sends it back. The other shards stayed free for other work: that is how sharding adds speed.
Now the app wants the total of all orders: SELECT sum(total) FROM orders. There is no customer_id in it, so the router cannot pick one shard. It sends the query to all 3.
Each shard sums only its own rows: 60, 80 and 60. The router adds the parts: 200, the same answer one server gives. It works, but it keeps every shard busy, and the slowest shard sets the pace.
The hard parts
A good shard key spreads rows and work evenly and appears in most queries. If customer 7 becomes a huge customer, all of its orders and reads hit shard 1 while the others sit idle. That shard is a hot spot.
Add shard 3 and the rule becomes key % 4. Now 5 of the 6 rows have a new home and must be copied across. Real systems avoid most of this by splitting into many small pieces first and moving whole pieces.
What happens
;; step 1/10 · one table orders, all on one server id customer_id total 1 7 30 2 12 45 3 5 20 4 9 15 5 4 50 6 11 40 every INSERT and UPDATE goes to this one server replicas copy it, so they help with reads only a chip in the figure: c<customer_id> · <total>
To keep the arithmetic checkable, the figure uses customer_id % 3 directly. Real systems hash the key first, so neighbouring keys such as 7 and 8 land far apart; PostgreSQL’s hash partitioning takes the hash value, then the remainder. With a plain "key % N" rule, changing N moves most rows: here 5 of 6. Systems such as Citus, Vitess and Cassandra split the data into many more pieces than servers (or use consistent hashing), so adding a server moves only some whole pieces.