After some thought, and considering the clients needs/requests, using an EAV model was the correct answer here.
After doing some more research I decided to use Postrgresql and make full use of its HSTORE data type, which allows storing, searching, and indexing of key value pairs in a single field.
Here is a paper benchmarking hstore vs EAV: http://wiki.hsr.ch/Datenbanken/files/Benchmark_of_KVP_vs.hstore-_doc.pdf
The paper above benchmarks hstore vs an EAV table, and hstore came out way ahead.
Another option we considered was having a task table that covered all the bases:
id, name, value_1, value_2... note_1, notes_2
Obviously the thought of that killed me inside a bit, so I was either going to use a task_type attribute table:
a task is prescribed by an administrator to a user and has a task_type, the task_type_attributes are for all tasks of that type (ie, define that for a exercise task, we want to be able to store information about the intensity of the exercise, the time the exercise took etc).
Once the user brings up the task, they see the task_attributes as fields to fill out. They enter these fields, and the attribute_value they enter are then associated with the task_entry of the patient (which also states if they completed it, skipped it, etc)
task_attributes
- id
- task_type_id
- attribute
- attribute_value_type (for generating the desired fields on the app side - ie, knowing to have a dropdown vs a text input)
- min_value
- max_value
- required
tasK_entry_values
- task_entry_id
- task_type_attribute_id
- value
Hope this might be of use to someone. I'd also be interested in any and all criticism/feedback for this design.