我在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)。
请建议我上述哪个选项可以提高数据库的性能。
先谢谢
答案 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)在作为外键传播时更易于管理。但是,通过唯一约束继续强制执行自然键至关重要。