外键还是复合键?

Foreign Key or Composite Key?

我刚刚开始应用我读到的关于 table 关系的所有内容,但考虑到存在第三个关系,我对如何在具有 MANY-TO-MANY 关系的 table 上插入数据感到有点困惑table.

现在我有这些table。

主题

name
code PK
units
description

学年

schoolyearId PK
yearStart
yearEnd

schoolyearsubjects(多对多 table)

id PK
code FK
schoolyearId FK

但是上面的 schoolyearsubjects table 的问题是,我不知道如何从 GUI 中插入 schoolyearId。在 GUI 屏幕截图上,一旦单击 "Save" 按钮,就会出现包含 2 INSERTTRANSACTION语句 (to insert on subject) 和 (to insert on schoolyearsubjects) 将执行。如果我坚持上面的做法,我将不得不插入 schoolyearId。 schoolyearId绝对不会来自GUI。

我正在考虑将 schoolyearsubjectsschoolyear 的列更改为:

学年

--composite keys (yearStart, yearEnd)
yearStart (PK)
yearEnd (PK)

学年科目(多对多 table)

id PK
code (FK)
yearStart (FK) --is this possible?
yearEnd (FK) --is this possible?

1.) 更改列并制作复合键的解决方案是否可以插入 yearStartyearEnd 值而不是 schoolyearId

2.) 我的连接/链接 table schoolyearsubjects 是否正确?

3.) 你有什么建议?

如果有任何帮助,我将不胜感激。

谢谢。

假设您的参数 @code@yearStart@yearEnd 的值来自 UI:

INSERT INTO schoolyearsubjects ( code, yearStart, yearEnd )
SELECT @code, y.yearStart, y.yearEnd
  FROM schoolyear y
 WHERE @yearStart <= y.yearStart
       AND y.yearEnd <= @yearEnd;

...但我认为您的 schoolyearsubjects 存在设计缺陷,因为它允许重复,例如这样做:

INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );
INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );
INSERT INTO schoolyearsubjects VALUES ( 'code red', '2016', '2017' );

看起来会导致三个事实上的重复行。

根据您当前的方案,您可以通过以下请求插入 schoolyearId:


    INSERT INTO schoolyearsubjects (id, code, schoolyearId)
    VALUES ( ${id},
             ${code_from_GUI},
             ( SELECT schoolyearId
               FROM schoolyear
               WHERE yearStart=${start_from_GUI} AND yearEnd=${end_from_GUI})
           );

为此,需要在学年 table 中对 (yearStart, yearEnd) 的唯一约束。

关于您的其他问题:
1) 您可以在学年中使用复合键 table 它会以任何一种方式工作。
2) schoolyearsubjects 是正确的,因为它允许编写连接查询。如果你摆脱了 schoolyearId 列,那么你可能不需要 schoolyear table alltogether 因为你可能想要获得的所有数据都将在 schoolyearsubjects table.
中 3) article 可能有助于决定使用哪种类型的密钥。

对我来说,学年是一个时期,因此,这里没有必要使用代理键。这总是让事情变得更加混乱,并且为其开发图形界面总是更加困难(我说的是我们作为开发人员如何建模时期)。

如果你停下来想一想,经期本身就是独一无二的。你的经期会和对方一样吗?停下来想一想。即使你有,这也会在几年或不同的时间发生。所以我们已经有了学年的主键。从学年中删除 "schoolyard PK"。在此处将复合键与 yearStart 和 yearend 一起使用。因此,您的学年实体(将来 table)将像:

  • 年开始PK
  • 年终 PK

在中间 table 中,您将有 3 个字段作为复合主键(也是外键!):

  • 年开始 PK FK(从学年开始)
  • yearEnd PK FK(来自学年)
  • 代码 PK FK(来自主题)

这将允许一个时期只有一个主题。另一方面,如果您想要一个包含多个主题的句点,则必须在此处放置一个代理键。

现在,要绘制图形界面,您将只需要使用一个select框(组合框)。在这种情况下,您会将每个项目作为文本,类似于 "from year X to Y"(一个句点)。您的用户可以很好地理解和 select 它。

注意:无论如何,您可能没有接口中记录的ID,而是标识它的值。这是允许看到的,并且标识了他们剩余的记录。

但是,如果您没有句点作为唯一的东西,那么 "yearStart" 和 "yearEnd" 是主题实体中的字段,并且没有学年实体。老实说,实体 "schoolyear" 只应存在,如果你想重用它的记录与其他 table(s) 的其他记录的关系。我并不是说是或不是这种情况。也要小心。如果你这样做,你说每个时期只有一个主题(作为字段)。我不知道这是否正是您想要的。我们必须永远记住塑造 ER 图最重要的事情:

  • 上下文

检查你的上下文。它问什么?如果您有任何问题,请发表评论。如果您能在这里提供更多背景信息,我可以为您提供更多帮助。