How to shard a database like that of SO?
Sharding, or database partitioning, is usually done to allow parallel processing of chunks of data. Groups of records residing in different shards (partitions) can be processed independently of one another, thus effectively multiplying the database server capacity. 

The biggest problem to solve when deciding the partitioning scheme is to ensure that data that are usually processed together (e.g. sets of frequently joined records) reside in the same partition. As a result the columns used to join tables (or their subsets) are often used as the partitioning key. If this principle is not followed partitioning usually turns into a big performance issue, because parallel processing of partitions becomes dependent on retrieving related sets of records from other partitions.

Subsequently, for effective partitioning the database needs to be designed from the beginning with this possibility in mind. You can't usually just "slap" partitioning on an existing database, unless the data model and queries are very simple.