Evening all,
I’ve got another database modelling problem to put to you. I’ve got various solutions that use lots of join tables, or JSON embeds, etc; but what I want to know is how you’d solve the issue.
Playing around with recording CrossFit workouts, and the “constantly varied” part of their motto makes it a surprisingly tricky thing to model. If you haven’t got an understanding of CrossFit, this explanation might seem arbitrary and complex, but stick with me. Basically the schema needs to have a lot of flexibility in combining different workout structures together, but within those structures there are rigid rules.
A Workout can be many different things. There’s various types of workouts such as AMRAPs (As Many Rounds As Possible) where you have a list of movements and repeat them until the clock runs out, or For Time (and Rounds For Time) workouts where there’s a set amount of work to be done and you complete it as fast as possible. Then there are things like EMOMs (Every Minute On the Minute) where you perform a movement or group of movements every 60 seconds. Traditional strength workouts (sets x reps) also come into play.
Each workout type has their own logic and either need to be modelled separately or if combined into one single schema with such flexibility that there’s effectively no schema.
Workouts can be one or more of these simultaneously. For example, you might do a “Buy In” of for example 100 push ups and then move onto an AMRAP for the remaining time in this section (lets say 5 minutes). Then after a 2 minute rest you start a For Time workout where you complete it as fast as possible. In this case your score would be a number of reps (or rounds & reps) for part A (the AMRAP) and a time for part B (the For Time workout).
Sticking with just relational methods I’ve found I very quickly end up with lots of join tables and polymorphism, and it becomes a mess. A working mess, but a mess nonetheless that I suspect would break down very quickly if I needed to add a new type of workout.
On the other end of the spectrum I’ve also tried just dumping an array of structs (one for each workout type) into a JSON column in the Workout table. Querying in this case gets handled by moving the queryable elements (movements, equipment, etc) into regular relationships that sit along side the JSON blob. In effect the JSON is what’s required by humans and the relationships by the DB.
How would you solve an issue like this?