My requirements are:
This is a problematic situation, and none of the solutions appears "right". However option 1 is probably the best both in terms of simplicity and in terms of performance.
This is also the solution used in some commercial enterprise applications.
EDIT
another option that is available now, but didn't exist (or at least wasn't mature) when the question was original asked is to use json fields in the DB.
many relational DBs support now json based fields (that can include a dynamic list of sub fields) and allow querying on them
postgress
mysql