I'm actually working on the same sort of issue where I need to allow for custom fields. Definitely multiple solutions...each with their own issues!! You might find this link interesting:
http://discuss.fogcreek.com/joelonso...w&ixPost=28256
By the way, if you go with the 1st approach...say we have a user_contact table with three fields, user_id, field_name, and value., and we want to retrieve all users with a last name beginning with b, ordered by last_name then first_name. You could "flatten" the data like this:
select distinct tuc1.user_id,
(select field_value from tb_user_contact tuc2 where
tuc1.user_id = tuc2.user_id and field_name='first_name') as first_name,
(select field_value from tb_user_contact tuc2 where
tuc1.user_id = tuc2.user_id and field_name='last_name') as last_name
from tb_user_contact tuc1
where
(select field_value from tb_user_contact tuc2 where
tuc1.user_id = tuc2.user_id and field_name='last_name') like 'b%'
order by last_name,first_name
Not pretty, I know, but it does work. I haven't tried it on large datasets, however. Might just be faster to build a temp table and munge the data into it.
Another approach I've considered is to "serialize" the custom data into a blob field containing XML (to at least give the blob field some structure). Doesn't make querying so easy though...or sorting.
I'm leaning towards the approach with a "base" TB_USER_CONTACT table and a TB_USER_CONTACT_CUSTOM table with the custom fields in it, and a Web-based interface allowing an end-user adminstrator to actually add/delete fields in the _CUSTOM table as needed. I'll then have a view VW_USER_CONTACT which simply joins the two tables on the USER_ID to abstract things a bit.
Good luck...
-Dave