Prisma 可以从关系表中创建一对多关系吗?

Posted

技术标签:

【中文标题】Prisma 可以从关系表中创建一对多关系吗?【英文标题】:Prisma can a one to many relationship be created from a relation table? 【发布时间】:2022-01-19 01:12:44 【问题描述】:

我正在使用 Prisma 和 mysql 创建一个锻炼应用程序。

我在用户和指定程序之间存在多对多关系,在模型“ProgramEnrollment”中显示。我遇到的问题是我希望用户记录他们的个人锻炼设置。

我的想法是创建一个新模型“LoggedWorkoutSet”,然后通过一对多关系将其连接到模型“ProgramEnrollment”,这意味着一个“ProgramEnrollment”可以有多个“LoggedWorkoutSet”。这似乎对我不起作用,问题在于尝试在此处定义关系时:

program   ProgramEnrollment @relation(fields: [programId], references: [id])
  programId Int // relation scalar field  (used in the `@relation` attribute above)

我得到的错误是“验证错误:参数references 必须仅引用相关模型ProgramEnrollment 中的现有字段。相关模型中不存在以下字段:id'

我不知道该怎么做,任何帮助将不胜感激。

model ProgramEnrollment 
  program                 Program     @relation(fields: [programId], references: [id])
  programId               Int // relation scalar field (used in the `@relation` attribute above)
  user                    User @relation(fields: [userId], references: [id])
  userId                  Int // relation scalar field (used in the `@relation` attribute above)
  assignedAt              DateTime @default(now())

  loggedWorkoutSet        LoggedWorkoutSet[]

  @@id([programId, userId])

model LoggedWorkoutSet 
  id              Int  @id @default(autoincrement())
  reps            Int
  weight          Int
  completed       Boolean     @default(false)

  author   ProgramEnrollment @relation(fields: [programId], references: [id])
  programId Int // relation scalar field  (used in the `@relation` attribute above)

【问题讨论】:

我唯一能想到的就是创建另一个模型,例如“LoggedProgram”,然后在“LoggedProgram”和“ProgramEnrollment”之间创建多对多关系,然后在它们之间创建一对多关系在“LoggedProgram”和“LoggedWorkout”之间。 你的数据真的是 1:many 而不是 many:many? 对不起,詹姆斯,我不太明白你的意思。用户可以完成许多程序,所以这将是多对多的关系。你的意思是“程序”和“LoggedSet”表之间的关系,如果你是对的,那将是一对多的关系。这是否意味着它不需要连接到“ProgramEnrollment”表?它是否应该通过一对一关系连接到“Sets”(上面未显示模式)表? “用户可以完成许多程序,所以这将是多对多” - 仅当其他用户可以完成相同的程序时。我可以帮助处理 SQL;我对 Prisma 一无所知。 谢谢瑞克,感谢您的回复。完全不用担心,不需要 Prisma 知识,这是我正在努力解决的 SQL 设计。是的,确实是多对多,因为所有用户都可以完成相同的程序。例如,我有一个名为“Get Jacked”的程序,我会开这个程序,意思是写下所有的锻炼,然后任何选择完成这个程序的用户任意多次。我正在苦苦挣扎的部分是他们如何在每次选择完成程序时存储他们的个人数据(例如举重和代表)。希望这是有道理的。 【参考方案1】:
CREATE TABLE Users (
    user_id ...,
    ...
    PRIMARY KEY (user_id)
) ENGINE=InnoDB;

CREATE TABLE Programs (
    pgm_id ...,
    part_of_body ... -- legs/shoulders/...
    ...
    PRIMARY KEY (pgm_id)
) ENGINE=InnoDB;

-- Many-to-many, with stats:
CREATE TABLE UserPgm (
    user_id ...,
    pgm_id ...,
    latest_date DATE ...,
    reps SMALLINT UNSIGNED NOT NULL,
    weight SMALLINT UNSIGNED NOT NULL,  -- in the normal units for this device
    PRIMARY KEY(user_id, pgm_id),
    INDEX(pgm_id, user_id)
) ENGINE=InnoDB;

使用所有 3 个表的查询:

-- The latest workout for a user:
SELECT u.name,
       up.latest_date,
       up.reps,
       p.device_name
    FROM Users    AS u
    JOIN UserPgm  AS up  USING(user_id)
    JOIN Programs AS p   USING(pgm_id)
    WHERE user_id = 123

【讨论】:

感谢瑞克的帮助。因为用户有多个锻炼和多个组,创建一个“UserWorkout”表和“UserSets”表以避免在“UserPgm”表中创建过多的列是否明智? @adherb - 可能。思考 1:many 与 many:many 的关系。

以上是关于Prisma 可以从关系表中创建一对多关系吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 或实体框架中创建没有主键的一对多关系?

如何利用 Prisma 的隐式关系来创建以下关系? (一对多,多对多,一对一)

Prisma 插入关系一对多

Prisma 上与 Self 的一对多关系

在 FuelPHP 中创建一对多关系

在Yii2中创建一对多关系