代码之家  ›  专栏  ›  技术社区  ›  palmsey

“属于”DB关系最佳实践?

  •  0
  • palmsey  · 技术社区  · 16 年前

    我在摄影场工作。网站上的照片将始终只属于一个事件。我最初的设计是:

    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
    

    在我看来,事件关系数据在照片表中有点肮脏/混乱-原始设计将照片、事件和关系分开-但它确实避免了连接,并且它强制关系到“有一个/属于”而不是“有多个”-您怎么想?

    6 回复  |  直到 16 年前
        1
  •  5
  •   tpdi    16 年前

    对于一对多关系来说,你的第二个选择是标准的、正常的、正确的方法。

    不过,你呢 完全地 当然,你在第一次拍摄时画的“多对多”关系不适用吗?我不太确定,但你比我更了解你的领域。

    编辑:

    手术室添加了一条评论;

    谢谢。我真的不相信照片应该属于一个以上的事件-事件是照片拍摄,每一张照片的定义是从一定的拍摄,并按事件查看是唯一的方式浏览网站。我很有信心一对多是正确的。

    这篇评论中有几节课,所以我想编辑这篇文章来强调这些课。

    观察1。最重要的是,在不知道两件事的情况下,您无法对模式进行建模:正在建模的实际问题域, 我们的解决方案对模型的要求。

    我最初的猜测是,OP的事件和图片是模拟 显示 活动中的照片,如美术馆(或网站上的图片库)。在这种情况下,例如,安塞尔亚当斯在线画廊很可能有活动,其中安塞尔亚当斯的照片显示,标题为“亚当斯的成熟作品”,“亚当斯的结构照片”,或“亚当斯的沙漠照片”。所有三个活动都可能包括亚当的 "Transmission Lines in the Mohave Desert", 1941 . 因为许多照片可以在许多事件中显示,所以我们需要多对多的结构。

    但这次行动的“事件”是 照片拍摄 很明显,正如操作说明,任何一张照片都是在一张照片中拍摄的,而只有一张照片。

    这里的教训是,在我们了解问题域之前,我们不能建模(或者只能临时建模)。

    我还建议更改表名“events”,使其更明确。称之为“拍摄”或“照片拍摄”使我们更清楚地了解我们在做什么。

    观察2。该报的评论回答了他的反对意见,即在照片中出现FK事件是“混乱的”。OP非常敏锐地意识到这“确实避免了连接,它强制关系到‘有一个/属于’而不是‘有多个’”。(避免连接是一个实现问题,正确的关系更为基础,因为它是一个建模问题。)

    他还应该意识到,在我们的解决方案中,在问题领域,有必要问一张照片,“这张照片是在什么照片会议/活动中拍摄的”。这就是为什么它不凌乱的原因:“在哪个阶段拍摄”是关于照片或照片属性的合法问题,而fk提供了这个问题的答案。这也意味着在这种情况下,从照片到事件的fk不应该为空:照片 必须 有一个照片会议,否则可能没有照片。

    (这里还有一些附加的课程,关于一对多关系或多对多关系的含义,以及使FK可以为空或不可以为空的含义,我将把它们放到另一个时间。)

        2
  •  3
  •   Erling Thorkildsen    16 年前

    我不能说我一直倾向于用你的第一个选择来做类似的事情。我会和第二个一起去。减少查询的使用。简单地按排序顺序对查询进行排序也可以。

    补充:我使用第一张专辑的唯一原因是,如果你(至少在某一点上)想制作它,这样照片就可以添加到多张专辑中,而事实并非如此。

        3
  •  1
  •   graza    16 年前

    第二种设计是最干净的。在第一个设计中,你 能够 在照片和事件照片表之间使用“有一个”关系,但这样将它们分开确实没有意义。如果在未来,你认为你需要多对多的关系,那么只有在那个阶段,改变设计回到原来的。

    干杯, 政府科学研究机构联合会。

        4
  •  1
  •   yukondude    16 年前

    我同意其他人的观点,他们指出你的第二个选择是实现一对多关系(一个事件,许多照片)的公认方法。一个面向对象的背景会让你觉得在照片表中有一个事件外键列是两个独立实体不舒服的耦合。但是从关系数据库的角度来看,这就是它的实现方式。

    在防止照片用于多个事件的同时,保留您的第一选择的唯一方法是在eventphotos的photoid列上放置一个唯一的约束。事件照片和照片之间的关系将变成一对一的关系,这有点毫无意义,但是您确实获得了照片和事件的分离。

    您的选择,但多年来成功的关系数据库设计仍将为第二个选项争论不休。

        5
  •  0
  •   Cyril Gupta    16 年前

    我投第二票。不需要单独的事件照片表。

        6
  •  -3
  •   Kthevar    16 年前

    任何两种设计都会导致一对多关系的宣传,你会在第二个是虚拟的一个更多的加入。但接下来的好的数据库设计,我会更喜欢第一个。你可以这样想,如果只有照片表需要与其他一些表的关系,这次你在这个表中的eventid没有任何作用。

     For samll level db design i would prefer 2 but for large or medium scale i would prefer the first.