使用 Prisma 的 MySQL 锻炼应用模式

Posted

技术标签:

【中文标题】使用 Prisma 的 MySQL 锻炼应用模式【英文标题】:Workouts App Schema for MySQL using Prisma 【发布时间】:2021-11-28 02:52:32 【问题描述】:

我正在使用 mysql 和 Prisma 创建一个锻炼应用程序,并且正在努力为数据设计架构。

该应用将拥有用户和锻炼计划。例如,锻炼计划“Get Jacked”可能包含 3 个块(每个块为 1 个月)。每个街区每周将包含 5 次锻炼,每次锻炼将包含多次锻炼和热身。需要注意的一些重要事项:每个用户都应该能够为锻炼中的每个练习记录他们的个人设置和代表。他们还应该能够完成一个程序(“Get Jacked”),他们喜欢多少次都可以,并且每次他们都应该能够为他们的代表和组记录新的值。

到目前为止,这是我的模型:

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

我对关系数据库比较陌生,我似乎无法理解代表的记录如何与用户联系,以及用户如何多次完成锻炼计划。

任何帮助将不胜感激。

谢谢, 亚当

【问题讨论】:

【参考方案1】:

你已经接近了,只是一些建议:

将 VSCode 与 Prisma 扩展一起使用,它将帮助您轻松格式化关系并更快地发现错误 声明关系的双方 尝试将您的数据库模型抽象为易于理解的概念,这样以后维护会变得更容易

这可能是你想要的:

// 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

【讨论】:

感谢维克多,感谢您的帮助。你知道是否可以从关系表中创建一对多关系吗?

以上是关于使用 Prisma 的 MySQL 锻炼应用模式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Prisma 的嵌套创建查询返回未定义

模式拼接两个远程 Prisma/GraphQL 模式

GraphQL 和 Prisma:当它们已经是 Prisma 数据库模式的一部分时,为啥要在应用程序模式中重新定义类型?

如何使用 Github-actions 在 Docker 上使用 Mysql 运行 Prisma 迁移

Prisma GraphQL 模式和数据模型之间的同一字段可以有不同的类型吗?

Prisma:跨数据库中的多个模式进行查询