我正在摄影网站上工作。网站上的照片将始终属于一个事件。我最初的设计是:
Table: Events
ID, Title, etc
Table: Photos
ID, ThumbnailURL, etc
Table: EventPhotos
EventID, PhotoID, SortOrder
这对我来说似乎很自然,但我意识到它描述的关系实际上允许照片属于许多事件。我曾经考虑像这样重构它,它只允许照片属于一个事件:
Table: Events
ID, Title, etc
Table: Photos
ID, EventID, SortOrder, ThumbnailURL, etc
事件关系数据在照片表中 - 原始设计将照片,事件和关系分开 - 对我来说似乎有点脏/乱 - 但它确实避免了连接,并且它强制关系到a'有一个/属于'而不是'有很多' - 您怎么看?
答案 0 :(得分:5)
对于一对多的关系,你的第二次采取是标准的,正常的,正确的做法。
但是,您完全确定您在第一次拍摄中勾画的多对多关系不适用吗?我不会那么肯定,但你比我更了解你的领域。
编辑:
OP增加了评论;
感谢。我真的不相信照片应该属于多个事件 - 事件是照片拍摄,每张照片都是根据某个拍摄的定义,并且按事件查看是浏览网站的唯一方式。我非常有信心一对多是正确的。
该评论有几个课程,所以我想编辑它以强调这些课程。
观察1.最重要的是,如果不了解两件事情,就无法对模式进行建模:正在建模的真正问题域,和我们的解决方案对模型的要求。
我最初的猜测是,OP的事件和图片是在事件中为照片的显示建模,如在艺术画廊(或网站上的图片库)。在这种情况下,例如,安塞尔·亚当斯在线画廊可能会有很多活动,其中显示的是安塞尔·亚当斯的照片,标题为“亚当斯的成熟作品”,“亚当斯的结构照片”或“亚当斯的沙漠照片”。所有这三个事件都可能包括亚当的"Transmission Lines in the Mohave Desert", 1941。由于许多照片可以在许多事件中显示,我们需要一个多对多的结构。
但OP的“事件”是照片拍摄,显然,正如OP所说,任何一张照片都是在一张照片中拍摄的。
这里的教训是,在我们了解问题域之前,我们无法建模(或只能暂时建模)。
我还建议改变表名“事件”,以使这一点显而易见。将其称为“拍摄”或“photo_shoot”可以更清楚地了解我们的建模。
观察2. OP的评论为他的反对提供了答案,即在照片中发生事件FK是“混乱的”。 OP非常敏锐地意识到这“确实避免了加入,并且它强制关系到'有一个/属于'而不是'有很多'”。 (避免连接是一个实现问题,正确的关系更为基础,因为它是一个建模问题。)
他应该意识到的是,在我们的解决方案中,在问题域中,询问一张照片是有意义的,“这张照片是在什么照片会话/活动中拍摄的”。这就是为什么它并不凌乱:“在哪个会话中采用'是关于照片的合法问题或属性,而FK提供了该问题的答案。这也意味着在这种情况下,从照片到事件的FK应该是'可以为空:照片必须进行照片会话,否则可能没有照片。
(这里还有一些额外的课程,关于如何建立一对多的关系或多对多的关系,以及让FK可以为空的意义是什么意思;我会把它们放到另一个时间。)
答案 1 :(得分:3)
我不能说我曾经倾向于使用你的第一个选择。我会选择第二个。将使用更少的查询。简单地按SortOrder对查询进行排序也可以正常工作。
补充:我使用第一个的唯一原因是,如果你愿意(至少在某些时候)喜欢这样做,那么可以将照片添加到多个专辑中,但似乎并非如此。
答案 2 :(得分:1)
然后你拥有的第二个设计是最干净的。使用第一个设计,你可以在Photos和EventPhotos表之间使用“has one”关系,但它真的没有意义将它们分开。如果在将来,您认为您需要多对多关系,那么只有在那个阶段才能将设计更改回原始关系。
干杯, GRA。
答案 3 :(得分:1)
我同意其他人指出你的第二个选择是实现一对多关系的可接受方法(一个事件,许多照片)。面向对象的背景会让您觉得在照片表中有一个事件外键列是两个独立实体的令人不舒服的耦合。但从关系数据库的角度来看,这就是它的完成方式。
保护您的第一选择,同时防止照片被用于多个事件的唯一方法是在EventPhotos的PhotoID列上放置一个唯一约束。 EventPhotos和照片之间的关系将成为一对一,这有点毫无意义,但你确实获得了照片和事件的脱钩。
您的选择,但多年成功的关系数据库设计仍然会争论第二种选择。
答案 4 :(得分:0)
我投票支持第二次拍摄。没有必要单独的事件照片表。
答案 5 :(得分:-3)
任何设计如何导致一对多关系,只有你在第二次得到的优点是avaoid再一次加入。但是好的数据库设计我会更喜欢第一个。你可以这样思考,如果只有照片表需要与更多其他表的关系,这次你在这个表中的eventID没有任何作用。
For samll level db design i would prefer 2 but for large or medium scale i would prefer the first.