Data Model (OpenMRS Implementer Meeting 2010)
Objectives:
Learn about the data model
... how concepts are related to other things
... how to extend the data model
... more about drug orders and encounters
"As an implementer, sometimes I don't understand why the programmers did things the way they did. I'd like to learn."
... how to deal with mental health data (lots of free text)
... so I can write better SQL queries
Push towards better documentation
... how much am I (i.e. Baobab) abusing it now?
... and learn what changes are coming
... more about problem lists and allergies
... how to manipulate the data
Notes
See an image of the data model on the OpenMRS wiki, under Developer Documentation
Broken down into domains (by color on the image)
Encounters
started off representing a visit, filled out from a form
we are growing beyond this
Encounters have types (e.g. initial visit, return visit, ...)
... link to a form (that was used to fill out the encounter)
... take place at a location (i.e. a physical, geographic location)
... have a timestamp
Upcoming change in 1.9: adding 'Visit' to the data model, which can group multiple encounters
Visits will have a start date and an end date
Upcoming change (after 1.9): adding 'Episodes of Care' which can group multiple encounters and visits
lots of overlap with program enrollments, workflows, and states
"Tags": this term to refer to "folksonomy" i.e. user-created tags that are not part of the core system
EAV (Entity-Attribute-Value)
the typical approach is for each question to be a column in the encounter table. As you start asking more questions, you need to add many many more columns. (This looks like a spreadsheet.)
EAV means you "turn this sideways" so instead of having one encounter with 50 columns, you would store one encounter and 50 observations.
Concepts represent the "questions" that would have been the many columns in a non-EAV encounter table
Observations
The core data in OpenMRS (as opposed to metadata)
concept_id -> the 'question' for this observation
value_xyz -> one of the value_xyz columns is filled in as the 'answer' for this observation
accession number -> used to link an observation back to a lab order that it originated from
value_group_id -> links multiple values for the same question
example 1: Chest Xray shows pneumonia AND infiltrate; as opposed to two chest xrays, one showing pneumonia, and another showing infiltrate
example 2: "Left" + "Upper Lobe" + "Pneumonia"
obs_group_id -> links multiple related observations that are all part of the same higher-level data point (e.g. Allergy cause, Allergy reaction, Allergy date)
Drugs
Why not just make these concepts? So we can representing both "Isoniazid" (a concept representing the generic drug) and "Isoniazid 300mg tablets" (an entry in the drug table)
UUIDs
Universally Unique IDs
You can create one of these anywhere, and you "always" (99.999...%) get a unique one
Concepts
Because of concepts we do not need to change the data model when we start asking new questions. We just add a row to the concept table
... has a datatype
for questions, this specifies the datatype of the answer
datatype=N/A means this concept is only an answer, not a question
... can be put in sets
... can be complex (i.e. datatype is not just a primitive String or Number, but rather something like a video or an xml document)
complex concepts have "handlers" which know how to store and display things (e.g. a video of an echo loop is stored in some database)
image and text handlers are built into the core system
multi-valued datatypes can be represented as an obs group (commonly done for allergies) or you can use complex concepts to store this as xml
'derived concepts' -> represents a calculation which lets you derive a value from other data (but you don't store data for a derived concept directy)
Example: "Pregnant?" -> diagnosis of pregnancy, or positive urine pregnancy test, or ...
Example: allows a report that has a "Pregnant?" question to be used against either obs for a boolean "is patient pregnant" or a datetime "expected delivery date"
Orders
Currently it's very simplistic in the data model
PIH is using the drug_order table now
Upcoming changes (not yet scheduled): much more sophisticated implementation of drug orders, lab orders, etc.
Regenstrief if building this on a data model derived from OpenMRS. We will copy a lot of what they do.
How do things get on the road map (e.g. why is order entry being built, but not billing)
"The community can drive whatever they want"
"If there's a portion of the data model that needs work from your perspective, then propose it"
Actually order entry is being worked on by Regenstrief for their own needs, and we're trying to leverage that work as much as possible
Upcoming changes to the data model that we know about:
In 1.7
Problem lists
Allergies
Location Hierarchy
Changes to Concept Name Tags
Boolean changes from 0/1 -> coded
In 1.9
Multiple providers per encounter
Visits
Addition attributes for Concept Mapping
Program Locations (when Jembi code is merged)
Orders (will change significantly if Regenstrief does a good job of implementing this)
How do you add a new address layout
You have to write xml, and put it openmrs-servlet.xml
We can probably commit your proposal to OpenMRS core
The columns in person_address can be renamed in the UI
Problem Lists
Can we support "continuing problems" (i.e. they have Fever, but this it's continued from before)
Allergies
Do these connect to the drug_ingredient table? Not yet. You can store allergies, but they don't do anything yet.
Can we support marking people as test patients? Would be nice--not quite sure how to do it?