【问题标题】:Parent-child relationship in many to many多对多的亲子关系
【发布时间】:2012-05-07 14:01:35
【问题描述】:

我正在尝试在 SQL Server 2008 中构建父子关系,但无法使其正常工作。

  1. 有 Presets(根级节点),然后有 PresetItems(子节点)。

  2. 一个 Preset 只能包含 PresetItems,但 PresetItems 可以包含其他 PresetItems 作为子节点。

  3. 可以构建许多 Preset,它们包含的 PresetItems 各不相同。

  4. PresetItem 可以在许多不同的 Preset 中重复使用,以构建不同的 Preset 配置。

其使用方式是动态创建报告。预设是报告的名称。 PresetItems 是报告的各个部分。这些部分(PresetItem)就像报告的一部分,例如“Year to Date Graph”。此 PresetItem 将包含文本说明,然后可以添加另一个包含图形的 PresetItem 作为此 PresetItem 部分的子项。

这个过程一直持续到报表的所有部分都组装完毕。

这是一个插图:

Client "A" Report (Preset 1)
   -- Overview (PresetItem 1) - contains boilerplate and maybe some dynamic data
   -- YTD Report (PresetItem 2) - contains boilerplate
      -- YTD Graph (PresetItem 3) - contains a graph created dynamically from SQL Server data
   -- Core References (PresetItem 4) - contains a table of dynamic data
   -- Summary (PresetItem 5) - contains boilerplate

Client "B" Report (Preset 2)
   -- Overview (PresetItem 1) - contains boilerplate and maybe some dynamic data
   -- Monthly Balance Sheet (PresetItem 8) - contains dynamic data
   -- YTD Report (PresetItem 2) - contains boilerplate
      -- YTD Graph (PresetItem 3) - contains a graph created dynamically from SQL Server data
   -- Summary (PresetItem 5) - contains boilerplate

...等等...

您会注意到一些 PresetItem 可以组合成许多不同的报告或预设。

这是我构建数据库表的方式,但我无法创建父子关系,因为多对多表中有两个主键。

Preset Table
-- Id (key)
-- Name

PresetItem Table
-- Id (key)
-- Name
-- Description
-- DataResource
-- (other columns)

PresetPresetItem (many-to-many table)
-- PresetId (key)
-- PresetItemId (key)
-- ParentId
-- SortOrder

我是否在正确的轨道上获得我正在寻找的结果?我无法在 PresetPresetItem 表中创建 PresetItemId 和 ParentId 之间的父子关系,因为它抱怨我遗漏了另一个主键 (PresetId)。

我明白它为什么会这样,但我现在不知道如何解决它。如果我说这一切都错了,请告诉我。

感谢任何帮助。

谢谢。

【问题讨论】:

    标签: database-design many-to-many parent-child


    【解决方案1】:

    有几种方法可以解决这个问题。

    可能最简单的一种是将每种“类型”的连接拆分为单独的表:


    或者,您也可以考虑从公用表继承 PresetItem,然后在 that 表的顶部实现图形边。不过,这可能对您的需求过于灵活:Preset 可能是另一个 Preset 甚至 Item 的孩子,这可能不是您想要的。

    【讨论】:

    • 我想这差不多了。这很好,因为“项目”需要独立于预设,但预设不能是其他预设的子项。我想我需要对此进行更多调查。感谢您的建议。
    【解决方案2】:

    我没有使用 SQL Server 的经验,因此我将这里的讨论限制在数据库设计上。

    在我看来这是你需要去的地方:

    如果 PresetItems 可以以严格的分层方式引用自己,则不需要第三个表。在这种情况下,只需给 PresetItems 一个外键返回给它自己。如果不是这样,我将不得不考虑如何实现多对多自我关系。

    但是,如果这个假设是错误的,那么你可能是在正确的轨道上!

    类似这样的:

    Presets
    -------
    presetId (PK)
    
    PresetItems
    -----------
    presetItemId (PK)
    presetIdFk (FK to Presets)
    presetItemIdFk (FK to PresetItems (self))
    

    这允许一个 Preset 到多个 PresetItem,并且 PresetItem 将被组织成一棵树。

    如果 PresetItems 不代表分层数据,你应该这样做:

    Many-to-many self-referential table

    【讨论】:

    • 感谢您的建议。我会试一试,看看会发生什么。顺便说一句,我使用的是 SQL Server 2008。
    • 实际上再次考虑您的建议似乎在这种情况下不起作用。您的建议将使 Preset 仅包含一个 PresetItem,并且它需要包含任意数量的预设项。我创建了一些临时表,但无法创建 SQL 语句来返回我需要的结果。
    猜你喜欢
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多