【问题标题】:Two foreign keys referencing the same primary key两个外键引用同一个主键
【发布时间】:2012-07-02 07:43:11
【问题描述】:

可以在一个表中有两个外键引用另一个表的一个主键吗?

EmployeeID 是员工表中的主键,在时间表表中作为外键出现两次。

很少有管理员用户代表其他员工填写时间表。

在 timsheet 表字段中,“TimsheetFor”将包含从事项目工作的人员的员工 ID,而“EnteredBy”或“FilledBy”字段将包含已填写此时间表的人员的员工 ID。

以下哪个选项是正确的?

注意:表格仅显示与此问题相关的字段。

【问题讨论】:

  • 是的,一张表中同一个pk有两个fk是可以的。
  • 是的 - 当然! 你为什么这么问?您看到的问题/问题是什么?
  • 我也想问同样的问题。我很高兴我是这个伟大网站的一部分!感谢您的回答:)

标签: asp.net sql vb.net normalization rdbms


【解决方案1】:

我会选择选项 1。让两个外键列引用不同表中的相同主键列是完全可以的,因为每个外键值将引用相关表中的不同记录。

我确信选项 2 会起作用,但您在 TIMESHEET_TABLETIMESHEET_FILLED_BY 之间基本上是一对一的关系,这使得两个表变得不必要并且更难维护。

事实上,如果ENTERED_BYTIMESHEET_FOR 都需要成对使用,则使用选项1 更有意义,因为这是由数据库和外键自动执行的。

【讨论】:

  • 我是 SSS,我赞同这个答案 :)
  • 它有效,但前提是两个 FK 都将删除和更新选项设置为无操作。如果你把“级联”或其他选项,它会给你一个错误。我在我的 SQL 2008 Server 上遇到了同样的情况,我有两个表,Currency 和 CurrencyHistory。 Currency 以 IdCurrency 作为主键,第二个表具有 IdCurrency 和 IdCurrencyRefference,它们必须与 Currency 表中的 Id 列相同。因此,我必须以编程方式从代码中进行删除或更新。就是这样:)
【解决方案2】:

选项 1 是一个完美的解决方案。您可以如下定义外键约束

Timesheet_For 列的第一个外键约束

ALTER TABLE TIMESHEETTABLE 
ADD CONSTRAINT fk_TimesheetTable_EmployeeTable
FOREIGN KEY (TIMESHEET_FOR)
REFERENCES EMPLOYEETABLE(EMPLOYEE_ID)

Entered_By 列的第二个外键约束

ALTER TABLE TIMESHEETTABLE 
ADD CONSTRAINT fk_TimesheetTable_EmployeeTable_1
FOREIGN KEY (ENTERED_BY)
REFERENCES EMPLOYEETABLE(EMPLOYEE_ID)

【讨论】:

    【解决方案3】:

    是的,这没有问题...您可以将另一个表中的一个表的主键用作外键两次。

    【讨论】:

    • 该方法的术语是什么..?,我想了解更多。
    • 这是一种常见的做法,我认为没有特殊的方法或术语。 @Harvest1018
    【解决方案4】:

    您的查询如下:

    SELECT t.EMPLOYEE_ID, a.NAME as TimeSheetFor, b.NAME as EnteredBy 
    FROM timesheet t
    JOIN employee a ON t.timesheet_for =a.employee_id
    JOIN employee b ON t.entered_by = b.employee_id
    

    使用这个查询你会得到你想要的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 2017-01-16
      • 2023-03-17
      • 1970-01-01
      • 2021-09-12
      • 1970-01-01
      相关资源
      最近更新 更多