使用两个以上的表创建外键

时间:2011-10-05 10:34:45

标签: sql database-design foreign-keys foreign-key-relationship

我有以下表格。

表格系统

  • sys_id
  • 名称

初​​级(sys_id)

表格请求

  • sys_id
  • REQUEST_ID
  • 受试者

初​​级(sys_id,REQUEST_ID)
外键requests.sys_id - > system.sys_id

表格字段

  • sys_id
  • FIELD_ID
  • 名称

初​​级(sys_id,FIELD_ID)
外键field.sys_id - > system.sys_id

表requests_props

  • sys_id
  • REQUEST_ID
  • FIELD_ID
  • FIELD_VALUE

初​​级(sys_id,REQUEST_ID,FIELD_ID)
外键requests_props(sys_id,request_id) - >请求(sys_id,REQUEST_ID)


在此之前,每件事都很好。所以我可以

  1. 使用特定的sys_id创建系统(在表系统中)
  2. 在此系统中创建一些字段(属性)(在表格字段中)
  3. 向系统添加请求(在表格请求中)
  4. 为与该系统的field_ids对应的每个请求设置字段值(属性)。 (在表requests_props中)
  5. 现在我想创建一个草稿请求集。 因此,每个请求可以有多个草稿。 草稿只是暂时的要求。 所以我决定遵循架构

    表格草稿

    • draft_id
    • sys_id
    • REQUEST_ID

    初​​级(draft_id)
    外键草稿(sys_id,request_id) - >请求(sys_id,REQUEST_ID)

    table drafts_props

    • draft_id
    • FIELD_ID
    • FIELD_VALUE

    primary(draft_id,field_id)
    foreign key drafts_props(draft_id) - >草稿(draft_id)
    外键??????????? drafts_props和fields table之间的关系

    这里我想创建表* drafts_props *到 fields 表之间的外键关系,我可以确保* drafts_props *具有相同的* field_id * * draft_id * 草稿表和* drafts_props *表之间的关联以及与该草稿相关联的* sys_id *。

    即。要查找drafts_props表中的有效field_ids,我首先必须将drafts_props表连接到drafts_id上的草稿表,然后找到与该草稿相关联的sys_id,然后在fields表中找到与该sys_id相关联的field_id。这将为我提供有效的field_ids。

    但据我所知,我不能使用3个表来创建外键约束。 外键[drafts_props]。[draft_id],[草稿]。[sys_id]引用[fields]。[sys_id],[fields]。[field_id]

    当然我也可以在表drafts_props中包含sys_id列,这样我就可以创建这样的约束,但我不想创建这种冗余。 我也无法更改表系统,请求,requests_props和字段。

    提前感谢!

2 个答案:

答案 0 :(得分:3)

sys_id中包含drafts_props的问题并不是它需要物理空间(它会,但这不是问题)。问题是,您最终可能会使用drafts_props行引用drafts并引用一个sys_id,同时本身会有不同的sys_id

这应该合法吗?

  1. 是的,只需在sys_id中包含drafts_props,在其PK之外。
  2. 如果没有,您将需要更改数据库模型,以便sys_id自然地向下传播识别关系并成为drafts_props主键的一部分。像这样:

    drafts (
        draft_id PK
        sys_id PK
        request_id
        FK (sys_id, request_id) -> requests
    )
    
    drafts_props (
        draft_id PK
        sys_id PK
        field_id PK
        field_value
        FK (draft_id, sys_id) -> drafts
        FK (sys_id, field_id) -> field
    )
    
  3. 其他建议:

    • 您可能还需要考虑某些主键中字段的顺序(即,您可能希望首先放置sys_id,具体取决于典型的查询模式。)
    • 如果您担心物理存储空间,一些DBMS(我知道Oracle,其他可能也是如此)可以相当有效地压缩包含大量重复的复合索引(例如,在您的情况下可能是sys_id )。有些甚至可以压缩表格数据。

答案 1 :(得分:0)

enter image description here