Frage

I have to design a simple relation

  • 1 "Workout" has multiple "Interval"
  • 1 "Interval" is present in only 1 "Workout", but it can be repeated multiple time in a "Workout"

I was thinking having this structure:
Interval
-id
-workout_id (foreign key)
-seq_workout

Workout
-id
-name

But with this structure, if an "Interval" is present many time in a "Workout", I have to insert multiple row of this Interval in the table with a different "seq_workout" (position where the interval is in the workout). I find this bad for using DB space that could be saved otherwise.

I could use a third table (interval_workout_position) Where I put the Interval id, the Workout id, and the position of the interval in the Workout. That way I could put the same interval multiple time in a Workout) Is there another solution, because I find using 3 table may be overkill for this?

Basically i'm just trying to reprensent an ArrayList with repeat possible (Workout has a QList of Interval ), for those familiar with Qt or ArrayList in other langage.

Thank you!

War es hilfreich?

Lösung

This is a one-to-many relationship.

Your relational design is sound. The table design you have supports these requirements;

An Interval occurs in exactly 1 Workout.

1 Workout has zero, one or more Intervals.

An Interval has a position (sequence) within a Workout.

There is no need for a third table, unless you are introducing another entity.


Update:

The table definition shown in the question is different than the table design added in the comment.

If you want to model a many-to-many relationship, you would use three tables.

interval
  id 
  message_en
  duration
  etc.

workout
  id
  name

workout_interval
  id
  workout_id    (fk references workout.id)
  seq_workout
  interval_id   (fk references interval.id)
  etc.

This model is a many-to-many.

The workout_interval table is the "relationship" between the Workout and the Interval. With this model

An Interval can appear in zero, one or more Workout, and a Workout can have zero, one or more Interval.

Any attributes that are specific to a particular Interval within a Workout can be added to the relationship table. Attributes of just the Interval (like a label or whatever), which doesn't change, those would be on the Interval table.

For example, if you are tracking workout results, you would record the weight and number of reps completed on the workout_interval table.


Update 2:

Given that you want an Interval to be used only in a single Workout, my the model in my previous update could be used, but it doesn't get you the constraint...

This model would provide that restriction. interval is a child of workout, and interval_seq is a child of interval.

workout
  id
  name

interval
  id
  workout_id    (fk references workout.id)
  message_en
  etc.

interval_seq
  id
  interval_id    (fk references interval.id)
  seq_           (position within workout sequence 1,2,3,...) 
  etc.

To get the intervals within a workout in sequence, with repeats:

SELECT w.id
     , s.seq_
     , i.*
     , s.*
  FROM workout w
  JOIN interval i
    ON i.workout_id = w.id
  JOIN interval_seq s
    ON s.interval_id = i.id
 WHERE w.id
 ORDER BY w.id, s.seq_

Andere Tipps

Just to say that I chose the solution with 3 tables from "spencer7593" :
-interval
-workout
-interval_workout (link between interval and workout)

It was the most natural way for me, I'm missing one small constraint (1 interval can only be in one workout) but I will be managing the insert in the table so I don't have to worry about that.

Now here is an example of a query I do to get all interval's workout for a specific user in my database, this query return me a xml file from my Rest webService that my application use to build workouts specific for a user: Now I need to see if Json is better than Xml in my application (using QXmlStreamReader from Qt now) and if there's a better way to code that query (currently hard-coded in a php page, hard to maintain) Thanks for your help!
└(°ᴥ°)┘ - To the moon! - └(°ᴥ°)┘

/* GET ALL INTERVAL WITH DETAILS IN SUBSCRIBED WORKOUT FOR USER=X */
 SELECT 
    /* plan */
    p.id plan_id, p.name_en plan_name_en, p.name_en plan_name_fr, 
    /* workout type */
    wt.id workout_type_id, wt.type_en workout_type_en, wt.type_fr workout_type_fr,
    /* workout */
    w.id workout_id, w.name_en workout_name_en, w.name_fr workout_name_fr, 
    w.descrip_en workout_descrip_en, w.descrip_fr workout_descrip_fr, w.creator workout_creator,
    /* seq_workout */
    iw.seq_workout, 
    /* intervalle */
    i.id intervalle_id, i.duration intervalle_duration, i.msg_en intervalle_msg_en, i.msg_fr intervalle_msg_fr,
    /* intervalle : power */
    i.power_start intervalle_power_start, i.power_end intervalle_power_end, i.power_range intervalle_power_range, i.power_left intervalle_power_left,
    /* intervalle : cadence */
    i.cadence_start intervalle_cadence_start, i.cadence_end intervalle_cadence_end, i.cadence_range intervalle_cadence_range,
    /* intervalle : hr */
    i.hr_start intervalle_hr_start, i.hr_end intervalle_hr_end, i.hr_range intervalle_hr_range,
    /* intervalle type */
    it.id intervalle_type_id, it.type_en intervalle_type_en, it.type_fr intervalle_type_fr,
    /* intervalle : step type */
    isPower.id intervalle_steptype_power_id, isPower.type_en intervalle_steptype_power_type_en, isPower.type_fr intervalle_steptype_power_type_fr,
    isCadence.id intervalle_steptype_cadence_id, isCadence.type_en intervalle_steptype_cadence_type_en, isCadence.type_fr intervalle_steptype_cadence_type_fr,
    isHr.id intervalle_steptype_hr_id, isHr.type_en intervalle_steptype_hr_type_en, isHr.type_fr intervalle_steptype_hr_type_fr
 FROM user u
 INNER JOIN user_groupe ug
 ON u.id = ug.user_id
 INNER JOIN groupe g
 ON ug.groupe_id = g.id
 INNER JOIN groupe_plan gp
 ON g.id = gp.groupe_id
 INNER JOIN plan p
 ON gp.plan_id = p.id
 INNER JOIN workout w
 ON p.id = w.plan_id
 INNER JOIN workout_type wt
 ON wt.id = w.workout_type_id
 INNER JOIN intervalle_workout iw
 ON w.id = iw.workout_id
 INNER JOIN intervalle i
 on i.id = iw.intervalle_id
 INNER JOIN intervalle_type it
 on i.intervalle_type_id = it.id
 INNER JOIN intervalle_steptype isPower
 on isPower.id = i.power_steptype_id
 INNER JOIN intervalle_steptype isCadence
 on isCadence.id = i.cadence_steptype_id
 INNER JOIN intervalle_steptype isHr
 on isHr.id = i.hr_steptype_id
 WHERE u.id = 1
 ORDER BY iw.workout_id, iw.seq_workout;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top