架构:双向关系?哪个表/实体应该拥有'偏好'?

sma*_*dev 2 sql database-design database-schema

我不确定如何提出这个问题,所以我会尽可能清楚地举一个例子.

在像facebook这样的应用中,个人资料可以有多个ProfilePictures.在任何给定时间,其中一个是"选定的"ProfilePicture(假设已经上传了ProfilePicture).

本能地,我会模仿这样:

Table: Profile
--------------
ProfileID
SelectedProfilePictureId //fk to ProfilePicture
Name, Age, Etc

Table: ProfilePicture
---------------------
ProfilePictureId
ProfileId //fk to Profile, indicating which Profile this picture belongs to
Url, DateTaken, Etc
Run Code Online (Sandbox Code Playgroud)

在这一点上,这些表格相互指向对我而言似乎"错误".它可以轻松查询没有SelectedProfilePictures的Profiles或获取Profile的SelectedPicture,但插入和更新有点不稳定.

这是不好的形式?Profile表是否应该与ProfilePicture表完全独立?是否存在根据数据库设计理论对其进行建模的"正确"方法,还是由程序员的排泄决定?

Ken*_*wns 6

你是对的,这被称为循环引用,你实际上无法使数据库这样做.

一个简单的解决方案是子图片表上的"首选"标志.但是你在这里有一个商业逻辑问题:对于给定的人来说,只有一行是首选.因此,当任何人标记新的首选时,您必须清除任何其他人.

更安全的解决方案是使用外键向Profiles和ProfilePictures添加第三个表"preferredPictures".在profileId上使其唯一,因此它永远不会有多个条目.这会强制在插入新条目之前删除先前条目.或者您当然可以更新现有的.

编辑:回应评论.

1)没有循环引用,因为"个人档案"是两个子表的父级,它不会循环到"个人档案"

Profiles
   |  |
   |  +-----> PreferredPicture
   |  +----->
   |  |
  \|/ |
ProfilePictures
Run Code Online (Sandbox Code Playgroud)

2)首选图片的主键是ProfileId,它在技术上是Profiles的1:1子表.