Nice and concise article. I would like to add a few points:
Before sharding, we should definitely consider vertical partitioning.
Sharding fits nicely for key-value stores, but what if you're not a key-value store?
Actually, it doesn't matter. We just need to generate a hash from the given key(s) to a range [0,numberOfShards-1]. For example, you can have a table with a composite Primary Key as (employeeId (int), department (string)).
Even in the above scenario, we can hash it to an integer and then take modulo with numberOfShards.
Important ⚠️: We need to think a bit about the hash function and numberOfShards value and ensure that data gets evenly spread.