【问题标题】:How do I change this schema into 3NF?如何将此模式更改为 3NF?
【发布时间】:2019-05-08 05:20:44
【问题描述】:

我创建了以下两个表格,用于历史教室环境。这些表格将包含有关历史上的战争以及参与其中的国家的数据。

我的问题是 Wars 表不在 3NF 中,因为 Combatants 字段中有多个值,因为战争中可能有许多战斗人员(即国家)。

如何在不创建任何人工键的情况下将此架构更改为 3NF(即仅使用我当前拥有的字段)?

CREATE TABLE Wars (
  Name CHAR(50) PRIMARY KEY,
  StartingDate DATE NOT NULL,
  EndingDate DATE NOT NULL,
  Cause CHAR(50) NOT NULL,
  Combatants CHAR(50) NOT NULL,
  TodaysDate DATE DEFAULT SYSDATE,
  CONSTRAINT CHK_TD CHECK(EndingDate < TodaysDate),
  CONSTRAINT CHK_SD CHECK(StartingDate > 0);

CREATE TABLE Nations (
  Name CHAR(50) PRIMARY KEY,
  StartingDate DATE NOT NULL,
  EndingDate DATE,
  TodaysDate DATE DEFAULT SYSDATE,
  CONSTRAINT CHK_TD CHECK(EndingDate < TodaysDate);

【问题讨论】:

  • 每个战斗员是否也与一个国家(甚至国家)有关联?
  • 是的,每个战斗员都是一个国家。
  • 哦,我明白你的意思是“战斗人员”是国家,而不是人或其他任何东西。它有助于在整个架构中以相同的方式命名相同的实体!那么我假设每个国家也可以出现在不止一场战争中?如果是这样,那么您需要实现多对多关系,并使用第三个表表示该关系。
  • 顺便说一句,您对这里的人工密钥有什么反对意见?我会说数字 ID 将是国家和战争表的理想键......这样,如果一个国家改变了它的名字,或者你意识到你打错了,或者你想重新标记一场战争,那么你可以这样做所以不违反任何关键约束。使用名称或描述字段作为键通常被认为是不好的做法,因为从长远来看,它们几乎总是会发生变化
  • 我在下面写了一个正式的答案。如果对您有帮助,请记得将其标记为已接受 - 谢谢!附言纯粹从学术角度来说,如果所有战争的起因都可以用一个 50 个字的领域来概括,而不是无穷无尽的书籍和论文的主题,那该多好啊! :-)

标签: sql oracle database-normalization


【解决方案1】:

你在这里得到的是一个多对多的关系,其中一场战争可以涉及多个国家,而一个国家可以参与多个战争。

在您的架构中表示这一点:

1) 从您的战争表中删除“战斗人员”字段

2) 创建一个“NationsWars”表(或任何您想称呼它的名称)。它只需要包含国家名称和战争名称。

3) 这两个字段中的每一个都将有一个外键返回到它们各自父表的主键。

4) 这个新表的主键将是由上述两个字段组成的复合键。

这是表示这种多对多关系的经典标准方式。


注意我不确定你为什么反对这里的人工钥匙。我会说数字自动增量 ID 将是国家和战争表的理想键......这样,如果一个国家改变了它的名字,或者你意识到你打错了,或者你想重新标记一场战争,那么您可以在不违反任何关键约束的情况下这样做。使用名称或描述字段作为键通常被认为是不好的做法,因为从长远来看,它们几乎总是会发生变化。主键应该是唯一且永久地标识特定记录的东西,并且没有其他上下文含义。

【讨论】:

  • 感谢您的帮助!这应该可以解决我的问题。
  • 值得注意的是,NationsWars 表有时被称为bridge tableassociative entity。此类表需要表示 SQL 数据库中的多对多关系,因为它们本身仅支持多对一关系(通过外键)。
  • 这与规范化无关。
  • @philipxy 我很想知道你为什么这么认为?由于“Combatants”字段中的重复组(它包含逗号分隔的值),原始数据处于非标准化形式。所以我们在这里所做的就是消除这个问题。为了在两个表之间创建正确的链接,我们还添加了一个新表来表示关系。由于国家表已经存在,所以我们也不需要添加它。如果出于所有实际目的,该过程不是标准化,那么也许我不知道是什么。也许你能启发我们?干杯。
  • 因为它与规范化无关。该术语用于表示两个不同的相关事物中的一个或两个——归一化为“1NF”和归一化为更高的 NF。该问题提到了 3NF,因此它至少与后者有关。你不需要我去了解更多。读一本教科书。目前尚不清楚“战斗人员字段中的多个值”是什么意思。根据定义,关系不能在一行中包含多个属性的值。 There's no one meaning for "1NF" & tons of nonsense is passed on about it.
猜你喜欢
  • 2016-02-15
  • 2013-06-20
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多