Prisma中包含选中对象的一对多关系最优建模方案咨询
建模方案结论
你提出的调整方案比原有建模更合理,是该场景下的更优实现,完全可以去掉Membership模型上的selectedBy和selectedById字段,仅在User侧保留选中关联即可。
原建模的缺陷
原有设计存在两个明显的逻辑冗余问题:
- 业务逻辑上,一个Membership(用户-组织成员身份)只能被它所属的用户选中,不可能被其他用户设置为当前选中身份,原模型没有对这种非法情况做限制,存在出现脏数据的风险
- Membership侧的
selectedBy关联属于完全多余的反向字段,额外增加了字段维护成本,切换选中身份时需要同时操作两张表,提升了出错概率
调整后方案的优势
仅在User模型上保留selectedMembership关联的设计有3个明显好处:
- 逻辑自洽:天然符合「用户选择自己名下的某一个成员身份作为当前使用身份」的业务规则,从根源上避免了跨用户选中成员身份的非法数据
- 维护成本低:切换选中组织时仅需要更新User表的
selectedMembershipId字段即可,操作原子性高,无需修改Membership表的任何内容 - 查询效率和原方案完全一致:通过
user.selectedMembership.organization即可直接拿到当前用户选中的组织信息,没有额外的关联查询损耗
调整后参考代码
model User { id Int @id @default(autoincrement()) memberships Membership[] @relation("Memberships") selectedMembership Membership? @relation("Selection", fields: [selectedMembershipId], references: [id]) selectedMembershipId Int? @unique } model Membership { id Int @id @default(autoincrement()) user User @relation("Memberships", fields: [userId], references: [id]) userId Int organization Organization @relation(fields: [orgId], references: [id]) orgId Int role MemberRole @@unique([userId, orgId]) }
补充优化建议
如果需要更强的数据一致性保证,可以在User表加一层check约束,确保选中的selectedMembershipId对应的成员身份确实属于当前用户,多数业务场景下应用层做校验即可满足需求。
内容的提问来源于stack exchange,提问作者Philippe Sabourin
相关产品推荐
相关产品推荐

