2

提前感谢您的意见。

我有 3 个对象:

  • 学校
  • 教练

具有以下关系:

  • 一所学校可以有多个营地。
  • 一个学校可以有多个教练。
  • 一个营地可以有多个学校。
  • 一个训练营可以有多个教练。
  • 一个教练可以有多个学校。
  • 一个教练可以有多个阵营。

多对多,School_Camp,显然将一所学校链接到一个带有日期附加字段的营地,以标识营地的年份。但是一个营地可以有多个教练。

::School_Camp::

  • School_id
  • Camp_id
  • 日期

设置另一个多对多 School_Camp_Coach 链接到 School_Camp 和 Coach 表对我来说会更好吗?

::School_Camp_Coach::

  • School_Camp_id
  • Coach_id

如果这是更有效的方法......我应该给 School_Camp 一个可以快速引用的独立 id 列,而不是使用三个字段作为标识符吗?

::School_Camp::

  • ID*
  • School_id
  • Camp_id
  • 日期

或者

有一个多对多表 School_Camp_Coach 和 3 个外键会更好吗?

::School_Camp_Coach::

  • School_id
  • Camp_id
  • Coach_id
  • 日期

我预见到的唯一问题是,您将有多个外键条目,但日期不同。

再次感谢。

4

3 回答 3

2

这不是效率问题,而是正确性问题:您提出的两个选项没有对表中记录之间的相同关系建模。

数据库中的每条记录都意味着某种东西。如果连接表中记录的含义是“X 在学校 Z 的营地 Y 执教”,那么您应该选择选项 2;如果您正在寻找独立于“X 为学校 Z 执教”和“学校 Z 跑营 Y”的含义建模“X 在 Y 营地执教”的含义,那么您应该选择选项 1。

在这两种情况下,您都应该为您的联结记录提供独立的主键,而不是依赖于 ID 的三向组合:当您实现对联结表应用更正的代码时,它将简化您的工作。

于 2012-04-24T22:00:30.467 回答
1

请参阅@Ted Hopp 的评论。

鉴于数据(学校营地每分钟不会发生多次),我认为更新时间不如检索时间优先。如果这是真的,我会选择你的最后一个选项,3 个外键。

这将是星型模式的一个示例。

于 2012-04-24T21:58:07.443 回答
0

对我来说,这个Coach实体看起来应该有我通常所说的一个basket,它可以与其他实体以多对多的关系链接。这就是我的意思:

# The coach model
CREATE TABLE coach(
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    name VARCHAR(20),
    capacity INT
) ENGINE=InnoDB;

# The coach data - who is using the coaches
CREATE TABLE coach_basket(
    coach_id INT,
    FOREIGN KEY(coach_id) REFERENCES coach(id),
    entity_id INT, /* the school or camp id */
    entity_type ENUM("School","Camp"),
    fromdate DATETIME,
    todate DATETIME
) ENGINE=InnoDB;

因此,现在您可以跟踪所有教练的使用情况,只需输入 entity_id(学校或营地 ID),以及他们每次使用教练的日期和时间。

您需要一个类似类型的表来存储连接的学校和营地,它可以如下所示:

# Store school-camp connections
CREATE TABLE connections(
    school_id INT,
    FOREIGN KEY(school_id) REFERENCES school(id),
    camp_id INT,
    FOREIGN KEY(camp_id) REFERENCES camp(id)
) ENGINE=InnoDB;

非常简单,只需保存学校和营地 ID,因此如果您查询一个 school_id,您会得到许多与学校相关的营地,反之亦然。

剩下的就是你的schoolcamp表,它们是模型(如顶部的教练表)。

于 2012-04-24T22:15:37.560 回答