【问题标题】:create foreign key using more than two tables使用两个以上的表创建外键
【发布时间】:2011-12-01 09:05:01
【问题描述】:

我有以下表格。

表格系统

  • 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
  • 字段值

主要(sys_id,request_id,field_id)
外键 requests_props( sys_id, request_id ) --> requests(sys_id,request_id)


到目前为止,一切都很好。所以在这里我可以

  1. 创建具有特定 sys_id 的系统(在表系统中)
  2. 在这个系统中创建一些字段(属性)(在表字段中)
  3. 向系统添加请求(在请求表中)
  4. 为与该系统的 field_ids 对应的每个请求设置字段值(属性)。 (在表 requests_props 中)

现在我想创建一个草稿请求集。 所以每个请求都可以有多个草稿。 草稿只不过是临时请求。 所以我决定遵循架构

表格草稿

  • draft_id
  • sys_id
  • request_id

主要(draft_id)
外键草稿(sys_id,request_id) --> 请求(sys_id,request_id)

表格草稿_props

  • draft_id
  • field_id
  • 字段值

主要(draft_id, field_id)
外键 drafts_props(draft_id) --> drafts(draft_id)
外键 ??????????在 drafts_props 和 fields 表之间 ????????????????

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

即要找到可以在 drafts_props 表中出现的有效 field_ids,我首先必须将 drafts_props 表连接到 drafts_id 上的 Drafts 表,并找到与该草稿相关联的 sys_id,然后在 fields 表中找到与该 sys_id 相关联的 field_ids。这会给我有效的 field_ids。

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

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

提前致谢!

【问题讨论】:

  • 请阅读您发布的问题,如果可能,请尽量简短,以便更易读,更有专家可以回答。

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


【解决方案1】:

drafts_props 中包含sys_id 的问题不在于它会占用物理空间(它会占用物理空间,但这不是问题)。问题是您最终可能会得到一个 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
    )
    

其他建议:

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

【讨论】:

  • 我很久以前就看到了您的建议,发现它很有用。谢谢。
猜你喜欢
  • 2021-12-30
  • 2016-03-06
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多