过多的表是否违反规范化规则?

Bur*_*gan 8 normalization database-design

这是我工作的数据库中存在的一些表的示例。数据实际上并不围绕学校,但结构是相同的。

有四张表:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Club **
Club Id, School Id, ClubType Id

** Student **
Student Id, Name, Club Id
Run Code Online (Sandbox Code Playgroud)

知道俱乐部表永远不会有额外的列(因为真实数据实际上不是关于学校俱乐部的),

我相信一个明显更好的设计,消除俱乐部表以避免连接,将是:

** School **
School Id, School Name

** ClubType **
ClubType Id, ClubType Name

** Student **
Student Id, Name, School Id, ClubType Id
Run Code Online (Sandbox Code Playgroud)

编辑:我们也知道每个俱乐部 ID 可能只有一种类型。Club 和 ClubType 的关系是 1 比 1。

我的问题是,第一个例子是否违反了一些已知的数据库规范化规则或其他一些数学原理?或者这只是一个糟糕的设计案例?

Mic*_*een 19

通过更改为您建议的解决方案,您会丢失数据库中的信息。现有的解决方案表明,在任何时间点,无论任何人实际上是否在该俱乐部中,都可以在特定学校中存在哪些俱乐部。提议的解决方案要求有人在俱乐部成立之前(即在将一行写入数据库之前)加入俱乐部。

作为实际含义,请考虑注册表单。这是学期开始的前一天。校长希望每个俱乐部的布告栏上都有一张报名表,以便学生可以加入。为所有俱乐部类型打印一张表格并让学生加入这所学校永远不会存在的俱乐部是一种浪费。今天,在学期开始之前,没有学生,因此您提出的解决方案将不起作用。然而,现有的解决方案允许委托人提供一个足球俱乐部,而不是一个水球俱乐部。

我意识到您正在使用学校/俱乐部的类比作为您实际情况的代理,并且您将不得不将我所说的全部转化为实际问题,并且我即将发表的评论可能不适用。这就是你为类比付出的代价。如果您的实际“学校”始终可以从所有“俱乐部类型”中进行选择,那么您提出的解决方案就足够了。

或者这只是一个糟糕的设计案例?

这不是糟糕的设计。也不是好的设计。它是一种实现了一些可供性但排除了其他的设计。它是出于我们无法访问的原因而编写的。它是用当时可用的知识编写的。可能它通过了大量测试和活跃的生产使用。

现在,从那时起,世界可能已经发生了变化。业务规则可能已经改变;实施团队的理解可能有所提高。该设计可能具有在给定数据的工作负载的硬件上不可接受的性能特征。更改该设计可能是合适的。


规范化是关于非键列如何依赖于单个表中的键列。它展示了如何更改架构,以便在现实世界中更改单个值将更新数据库中单行中的单列。关于从手头的现实世界问题实施场景,没有什么可说的。

我理解您当前的学生表的意思是“作为俱乐部成员的人”。这意味着主键将是 {student id, club id}。在您当前的实现中,该表未规范化,因为 Name 仅取决于学生 ID 而不是俱乐部 ID。规范化的解决方案是将表 Student 的语义更改为“A person”(列学生 ID、姓名)并创建一个包含列 {student id, club id} 的新表 ClubMember。

Club 和 ClubType 的关系是 1 比 1。

我对此表示怀疑。ClubType 的可能值是什么?也许是“足球”或“瑜伽”?我认为很多学校都希望有一个足球俱乐部。也许

Each Club     is-this-schools exactly one   ClubType  
Each ClubType is-offered-in   zero or more  Club
Run Code Online (Sandbox Code Playgroud)

作为 ERD:

ClubType --< Club >-- School
Run Code Online (Sandbox Code Playgroud)

  • 在考虑您的答案一段时间后,我现在更好地理解了我提出的两个设计之间的权衡。我的俱乐部类比现在似乎从根本上被打破了,但尽管如此,您的评论在很大程度上仍然适用。您提供的关键见解是我提供的第二个示例中不能存在空俱乐部。 (3认同)