I am creating a workout app using MySQL and Prisma, and I am struggling to design a schema for the data.
The app will have users and workout programs. For example a workout program 'Get Jacked', could consist of 3 blocks (each block is 1 month). Each block will contain 5 workouts per week, each workout will contain multiple exercises and a warm up. Some important things to note: each User should be able to record their personal sets and reps for each exercise within a workout. They should also be able to complete a program ('Get Jacked'), as many times as they like and each time they should be able to record new values for their reps and sets.
Here's my models so far:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
workouts Workout[]
}
model Program {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
name String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
model Block {
id Int @id @default(autoincrement())
name String
program Program @relation(fields: [programId], references: [id])
programId Int
}
model Workout {
id Int @id @default(autoincrement())
name String
week String
day String
block Block @relation(fields: [blockId], references: [id])
blockId Int
}
model WorkoutSet {
id Int @id @default(autoincrement())
name String
sets Int
reps Int
workout Workout @relation(fields: [workoutId], references: [id])
workoutId Int
exercise Exercise @relation(fields: [exerciseId], references: [id])
exerciseId Int
}
model Exercise {
id Int @id @default(autoincrement())
name String
}
model LogWorkout {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
workout Workout @relation(fields: [workoutId], references: [id])
workoutId Int
}
model LogWorkoutSet {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
sets Int
reps Int
weight Int
logWorkout LogWorkout @relation(fields: [logWorkoutId], references: [id])
logWorkoutId Int
workoutSet User @relation(fields: [workoutSetId], references: [id])
workoutSetId Int
}
I am relatively new to relational databases and what I can't seem to get my head around is how the recording of the reps ties back to the user and how the user can complete the workout program multiple times.
Any help would be much appreciated.
Thanks, Adam
Your'e getting close, just a couple of recommendations:
This might be what you want:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
programs Program[]
programRecords ProgramRecord[]
exercises ExerciseRecord[]
}
// Programs available
model Program {
id Int @id @default(autoincrement())
name String
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
blocks Block[]
records ProgramRecord[]
createdAt DateTime @default(now())
}
// Blocks within a program
model Block {
id Int @id @default(autoincrement())
name String
programId Int
program Program @relation(fields: [programId], references: [id])
workouts Workout[]
}
// Workouts within a block
model Workout {
id Int @id @default(autoincrement())
name String
week String
day String
blockId Int
block Block @relation(fields: [blockId], references: [id])
exercises ExerciseOnWorkout[]
}
// Exercises to be done in workout (Relation table)
model ExerciseOnWorkout {
id Int @id @default(autoincrement())
workoutId Int
workout Workout @relation(fields: [workoutId], references: [id])
exerciseId Int
exercise Exercise @relation(fields: [exerciseId], references: [id])
name String
sets Int
reps Int
weight Int
records ExerciseRecord[]
createdAt DateTime @default(now())
// Restrict to do not repeat combinations with same name
@@unique([workoutId, exerciseId, name])
}
// Exercise options
model Exercise {
id Int @id @default(autoincrement())
name String
workouts ExerciseOnWorkout[]
}
// New "enrollment" record of a user in a program
model ProgramRecord {
id Int @id @default(autoincrement())
programId Int
program Program @relation(fields: [programId], references: [id])
userId Int
user User @relation(fields: [userId], references: [id])
exerciseRecords ExerciseRecord[]
// TODO: You could track the status to prevent users starting a new one
isComplete Boolean @default(false)
createdAt DateTime @default(now())
}
// User personal record for a workout exercise
model ExerciseRecord {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id])
exerciseId Int
exercise ExerciseOnWorkout @relation(fields: [exerciseId], references: [id])
programRecordId Int
programRecord ProgramRecord @relation(fields: [programRecordId], references: [id])
name String
sets Int
reps Int
weight Int
createdAt DateTime @default(now())
@@unique([userId, exerciseId, programRecordId, name])
}
enum Role {
USER
}