规范化更好还是复合主键更好?

时间:2010-07-20 11:24:59

标签: database-design primary-key normalization composite-key

我在Oracle DB中有一个表,比如,Student表。 StudentID是表中的主键。我有另一列感兴趣的主题,比如列名是interest_SUB。学生可以有多个感兴趣的科目。在这种情况下,我有以下两个选项:

1)将StudentID和Interested_SUB列作为复合主键。           在这种情况下,例如,如果学生对3个科目感兴趣,那么我将在表中有3行,其中(S1,SUB1)(S1,SUB2)和(S1,SUB3)作为列值,所有其他列将具有相同的这三行的值。

2)有一个单独的表,其中包含StudentId和Interested_SUB列以及第一个表中的附加列,以指示学生是否对多个主题感兴趣。           在这种情况下,我将学生表中的每个学生一行,其中studentId和SUB为(S1,SUB1),新指示符列为“Y”。在第二个表(S1,SUB2)& (S1,SUB3)。

请建议我上述哪个选项可以提高数据库的性能。

先谢谢

5 个答案:

答案 0 :(得分:2)

学生表很可能包含很多关于学生的价值观。选项1的外观如何?例如。你想看看每一行的名字,年龄或学期吗?可能不是。

通常情况下,你自己的学生表和主题表都有。第三个表包含连接两个表的信息。在那里,您可以有多个属于同一个学生的行,但属于不同的科目:

students:  
1, Mister X  
2, Mister Y

subjects:  
1, Computer science  
2, Mathematics

students_subjects:  
1, 1  // Mister X likes computer science  
1, 2  // Mister X likes mathematics, too  
2, 2  // Mister Y likes mathematics only

这可能不如将所有内容写入一个表中那样高效。但是你不应该过早地考虑性能而没有理由。

答案 1 :(得分:1)

如果没有关于生产场景的一些指标(例如:有多少学生?有多少科目,有多个科目的学生的预期百分比是多少?),“绩效”很难判断。

另一方面,你的第二个解决方案在设计方面是非常糟糕的(它是反直觉的,依赖于通过查看数据库模式而不是立即明显的逻辑,如果有人想要删除其中一个,它会变得复杂他的兴趣......)甚至在相当不可能的情况下,它更“有效”,实际收益将因复杂性的增加而大大黯然失色。

因此,简而言之:忘记解决方案#2。

答案 2 :(得分:0)

在真实数据库中,对于大型表,密钥越简单越好。它使扫描和连接速度更快,并且消耗更少的RAM。人工数字键可能比非数字键和/或复合键更快,更具可伸缩性。

在你的情况下,一定要进行规范化。它不仅速度更快(行数更少),而且更好地表示域并且更不易碎(无需担心为一个学生保持多行同步)。

答案 3 :(得分:0)

如果不了解批次更多有关情况的话,无法真正回答与数据库绩效相关的问题:

  • 桌子有多大?
  • 学生可以拥有多少科目? (“不止一个”可以表示五个或一百个)
  • 会重复多少列?
  • 您将运行哪些类型的查询?
  • 你对桌子有什么索引?

即使这只是表面上的痕迹;你仍然需要测试才能明确地说出任何话。

一般来说,规范化是“更清洁”的选择,使事情变得更简单,更容易;但是,去标准化通常可以加快速度。除非你绝对需要额外的表现,否则我会使用标准化。

答案 4 :(得分:0)

您描述的是交叉表(AKA交汇点或链接)表。这是表示多对多关系的常见构造。您有一个学生表,其中包含有关学生(姓名,出生日期等)的一般信息,以及一个主题表,其中包含有关主题(姓名,教师等)的一般信息。您需要一个STUDENT_SUBJECTS表来显示哪些学生对哪些科目感兴趣。

至于密钥,没有硬性规定。理论有利于复合自然键(STUDENT_ID,SUBJECT_ID)。如果没有与表关联的其他列或数据,这将是我的选择。但是,想象其他数据可能依赖于STUDENT_SUBJECTS(例如ASSIGNMENTS,TESTS等)并不是不合理的。在这种情况下,合成主键(STUDENT_SUBJECT_ID)在作为外键传播时更易于管理。但是,通过唯一约束继续强制执行自然键至关重要。