0

I am trying to design a schema for the a clinical dataset, MIMIC-III. I am trying to figure out a way to store the events in a way such that users can query the dataset with ease using possibly a star schema. Almost all of the entries such as diagnoses, procedures, notes, charts etc. are related to a single admission. I had a few things in my mind but I have no experience so am finding it difficult to figure out what the best way to do this is.

  1. Create multiple fact tables, for example I would have one fact table for diagnoses, one for procedures, one for lab notes but this just seems like too many fact tables with little to gain. Like I could have a fact table with an entry for each diagnosis per user per admission but would that give me more benefit than the OLTP schema already implemented?
  2. Create one fact table with a row per admission with multiple columns/dimensions like diagnoses, procedures etc. But the issue with is that for most there are multiple diagnoses per admission so I will have to link to a bridge table in most fact tables and then it would look like the image below. The issue with this is the required joins for the queries.schema
  3. The third way that I read about is using something like an entity-attribute-value fact table where I have a fact table with each row being one fact. For example, one row could be something like (patientid - addmissionid - (Attribute) Heart Rate Reading - (VALUE) 120bpm) this would create a single fact table with almost everything inside and fewer joins required but it would require the end user to pivot the table after querying due to the nature of EAV's thus making it more complicated for the end user. It would look like the i2b2 star schema.
  4. The last way I thought of was doing an entry per event into the fact table but having many columns in the fact table to store dimensions, like (patientid, admissionid, icustay_id, diagnosis, procedure, labnote, labevent, microbiologyevent, etc.) in which patientid, and admissionid will be in all rows but the rest will depend on the entry so one entry could have just patientid, admissionid and a single procedure. I don't know how the end result of this will be like in terms of querying due to my lack of experience. I also don't know whether or not all these entries with almost every column being irrelevant is the way to go.

Any help would be greatly appreciated, I'm trying to have this implemented into BigQuery.

rmesteves
  • 3,870
  • 7
  • 23
  • Are you searching for best practices in BigQuery or for Dimensional Modeling strategies? – rmesteves May 11 '20 at 15:52
  • It is for dimensional modelling but my understanding is that BigQuery has more features like nesting and repeatedfields thus making the schema a bit different hence why I mentioned it. – user3083988 May 11 '20 at 16:55

2 Answers2

0

Some tests have concluded that reducing the number of joins can enhance the BigQuery's performance. In other words, if you denormalize most of your data in a single table you will probably get better results since you'll not need to perform many joins.

There are some points that you should think about when deciding the data modeling:

Is it easy to write queries in your model?

If you need many joins, your model will be probably difficult to build queries. If you use nested fields to reduce the number of joins you can simplify the queries you will write. However, if you create very complex nested structures, you will start having problems to query the model again.

Is it easy to join data in your model?

If you have many tables to be joined, your data will be difficult to join. The more denormalized the data is, the easier it is to join.

Easy to update data

If you need to update your data, you should consider that denormalization can help you. If you reduce the number of tables, you will need to update fewer tables. Its important to say that if you create very complex nested fields, it will also be difficult to be updated.

Make data understandable

This is the most important point. Will your data be understandable in a given model? All the previous points are technical and not exactly related to your data. You should design your model considering these points, but your data must make sense to you.

Finally, I would like to summarize some advice:

  1. You can get a better performance denormalizing your data as long as the data keeps understandable.
  2. Use nested fields to denormalize the model but try not creating very complex structures (more than 2 level of nesting).
  3. Keep in mind that your model will need more disk space when you denormalize it so your billing for storage in BigQuery will probably be higher.

I hope it helps

rmesteves
  • 3,870
  • 7
  • 23
0

Initial Reading

Trying reading The Data Warehouse Toolkit, chapter 14 has a section on healthcare data modelling.

Modelling vs Storage

But what you should try and figure out is what is the important and high value data, and what is the less important and low value data. Only model and load into the database the high value data. If you try and build the perfect data model, you are never going to deliver any useful reporting to your customers/clients.

  1. What will be used on a daily or hourly basis? This information needs to be in your data model and loaded into the database for aggregation and slicing.
  2. What will be used only occasionally? Once the slicing and dicing is complete, there will be further questions about the minutiae of a small cohort. This is when you go to the bulk storage and retrieve this data from your Data Lake.

Data Lake

Instrument measurements are great examples of low value information. Most individual measurements are not useful, but your ETL could review them and make an overall determination of some kind. E.G. Blood Pressure Normal, Heart Rate High, etc. Prescription drugs are another example of low value information. In the database you may set a flag if multiple prescriptions are present or something similar. Freeform notes are another. Once some cohort has been decided on based on many other factors, you enable a data scientist to process the note with some machine learning but doing this for all notes is not very useful.

Group/Junk Dimensions

A number of these measurement determinations could be lumped together inside of a group/junk dimension as a way of resolving maintaining the grain of the fact and keeping the fact from exploding with low value rows. You could even hold off on modelling a junk dimension until your customers/clients start telling you about long executions for specific types of data extracts. You can then design a junk dimension to serve these higher value measurement determinations to enable additional aggregations or slicing prior to extracting the insightful data from the data lake.

File Structure

In your data lake I would have many file schemas for the low value data. These could be JSON, parquet, csv, or whatever you prefer. You would include the data needed to connect it back to the fact along with the data specific to the file type. PatientId AdmissionId MeasureType MeasureValue Date Time

The point is most of this data will never be looked at, but occasionally a few records are high value. You just don't know which they will be, so you store them as cheaply as possible until they are needed.

The data lake also allows you to change your file schema as new information becomes available and executing this change is trivial compared with changing a database star schema.

Use your favourite scripting language to create these files. Python, C#, Azure Function App, AWS Lamda, whatever. This will depend on your own skills and resources available.

Community
  • 1
  • 1
Doran
  • 1
  • 3