Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 规范化更好还是复合主键更好?_Database Design_Primary Key_Normalization_Composite Key - Fatal编程技术网

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

Database design 规范化更好还是复合主键更好?,database-design,primary-key,normalization,composite-key,Database Design,Primary Key,Normalization,Composite Key,我在oracledb中有一个表,比如说,Student表。StudentID是表中的主键。我有另一个列“感兴趣的主题”,比如列名称“感兴趣”。一个学生可以有多个感兴趣的主题。在本例中,我有以下两个选项: 1) 将StudentID和感兴趣的_子列作为复合主键。 在这种情况下,例如,如果学生对3个科目感兴趣,那么我将在表中有3行,其中(S1,SUB1)(S1,SUB2)和(S1,SUB3)作为列值,并且所有其他列对这三行具有相同的值 2) 有一个单独的表格,其中列有StudentId和Intere

我在oracledb中有一个表,比如说,Student表。StudentID是表中的主键。我有另一个列“感兴趣的主题”,比如列名称“感兴趣”。一个学生可以有多个感兴趣的主题。在本例中,我有以下两个选项:

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

2) 有一个单独的表格,其中列有StudentId和Interest_SUB,并在第一个表格中增加一列,以表明学生是否对一个以上的科目感兴趣。 在本例中,我将为student表中的每个学生指定一行,其中studentId和SUB为(S1,SUB1),新的指示符列为“Y”。在第二个表中(S1,SUB2)和(S1,SUB3)

请建议我以上哪种选项可以提高DB的性能


提前感谢

学生表可能包含许多关于学生的值。选项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,X先生 2,Y先生 学科: 1、计算机科学 2、数学 学生与大学科目: 1,1//X先生喜欢计算机科学 1,2//X先生也喜欢数学 Y先生只喜欢数学
这可能不如将所有内容写入一个表。但是,您不应该过早地、毫无理由地考虑性能。

在实际数据库中,对于大型表,键越简单越好。它使扫描和连接速度更快,占用的内存更少。人工数字键可能比非数字键和/或复合键更快、更具可伸缩性


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

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

  • 这张桌子有多大
  • 一个学生最多可以有多少科目?(“一个以上”可能意味着五个或一百个)
  • 将重复多少列
  • 您将运行哪些类型的查询
  • 表上有什么索引
即使这只是表面现象;你仍然需要进行测试,才能明确地说出任何事情

一般来说,规范化是“更干净”的选择,使事情变得更简单、更容易;但非正常化通常会加快速度。除非你绝对需要额外的表现,否则我会选择标准化。如果没有关于制作场景的一些指标(例如:有多少学生?有多少科目,学生兴趣超过一个科目的预期百分比是多少),那么很难判断“表现”

另一方面,您的第二个解决方案在设计方面非常糟糕(它是反直觉的,依赖于逻辑,通过查看DB模式无法立即看出,如果有人想放弃他的兴趣,它会变得复杂…),甚至在不太可能的情况下,它更“高效”复杂性的增加将大大掩盖实际的收益


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

您描述的是一个交叉表(也称为连接或链接)表。这是表示多对多关系的常见构造。您有一个包含学生一般信息(姓名、出生日期等)的学生表和一个包含科目一般信息(姓名、教师等)的科目表。你需要一个学生科目表来显示哪些学生对哪些科目感兴趣


至于钥匙,没有硬性规定。理论支持复合自然键(学生ID、科目ID)。如果没有与表关联的其他列或数据,这将是我的选择。然而,想象其他数据可能依赖于学生主题(如作业、测试等)并非不合理。在这种情况下,合成主键(学生主题ID)作为外键传播时更易于管理。但是,通过唯一约束继续强制自然关键点至关重要

它的性能肯定不会下降。这就是路!