1

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

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) 中。

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

提前致谢

4

5 回答 5

2

学生表可能包含很多关于学生的值。选项 1 会是什么样子?例如,您想在每一行中查看姓名、年龄或学期吗?可能不是。

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

学生:  
1、X先生  
2、Y先生

主题:  
1、计算机科学  
2、数学

学生科目:  
1, 1 // X 先生喜欢计算机科学  
1, 2 // X 先生也喜欢数学  
2, 2 // Y 先生只喜欢数学

这可能不如将所有内容写入一张表那样高效。但是你不应该过早无缘无故地考虑性能。

于 2010-07-20T11:37:22.187 回答
1

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

另一方面,您的第二个解决方案在设计方面非常糟糕(它违反直觉,依赖于通过查看 DB 模式并不立即显而易见的逻辑,如果有人想要放弃他的兴趣,它会变得复杂。 ..),即使在不太可能的情况下,它更“有效”,实际收益也会被复杂性的增加所掩盖。

所以,简而言之:忘记解决方案#2。

于 2010-07-20T11:40:16.157 回答
0

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

在您的情况下,绝对要进行标准化。它不仅会更快(行更少),而且在表示域方面也更好并且更不脆弱(无需担心为一个学生保持多行同步)。

于 2010-07-20T11:37:51.307 回答
0

如果不了解更多情况,就无法真正回答与数据库性能相关问题:

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

甚至这只是表面现象;你仍然需要测试才能明确地说出任何事情。

一般来说,规范化是“更干净”的选项,让事情变得更简单、更容易;但是反规范化通常可以加快速度。除非你绝对需要额外的性能,否则我会选择标准化。

于 2010-07-20T11:38:58.443 回答
0

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

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

于 2010-07-20T12:32:19.463 回答