It sounds like you and I had very similar experience. :) Please do share and elaborate some time.
For my past implementation of a similar data-store we had some different requirements that let us cut a few corners. But, if I were to take another stab at it with your requirements then I would try a new approach.
I think I would use a single table to represent the 'event' itself and have that table be essentially owned by the customer. This table could be put on a specific shard set aside for each customer or you could just name it "{customerId}_{eventName}" and have a lot of tables. Then each event coming in would potentially perform an 'alter' on the table in order to make sure all custom properties have a column.
Are there any downsides to this approach I'm not considering?