简体   繁体   中英

Workouts App Schema for MySQL using Prisma

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:

  • Use VSCode with the Prisma extension, it will help you format the relations easily and find errors faster
  • Declare both sides of the relationships
  • Try to abstract your DB model into easy-to-understand concepts, that way maintenance will become easier later on

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM