我对规范化有点困惑。
有人可以在这个数据库中提供真实的例子吗?如果那没关系?谢谢。
表:account_info
student_number(PK)
student_username
student_password
表:student_info
student_number(PK)
student_name
student_course
student_year
student_section
table:student_subject
student_number(PK)
student_subject_1
student_subject_10
关于外键,我可以在上面的给定表中使用它吗?
何时何地是使用它的最佳时间?
答案 0 :(得分:3)
好吧,如果您对规范化有疑问,您可能应该阅读这个主题,然后提出具体问题。那说......
我在这里看到的关于你的模式的唯一不规范化的是student_subject_1,student_subject_2等。第一范式的规则之一是“没有重复的组”。也就是说,你不会在程序中使用数组或列表。无论何时开始编号字段,都应该退后一步,询问这不是重复组,即数组。
要进行的规范化标准化操作是将其更改为:
student_number
subject_index
subject_name
主键是student_number + subject_index。或者您可以创建合成ID,如序列号。
然后,您为每个主题创建一个记录,并使用索引来区分它们。
如果订单没有任何意义 - 如果#2也可以放在#3而#4放在#1等 - 那么我很可能会创建一个student_subject_id,它只是一个序列号。
这样做有很多充分的理由。
10个科目是绝对限制,永远不可能改变吗?如果没有,如果有一天学生出现了11个科目,那么你的课程将会中断。我遇到过这个系统曾经遇到过的问题,我认为这是“儿童”的8个插槽。我想有人说,“谁会有超过8个孩子?”然后当然有人有11个孩子。
假设您要搜索所有正在学习某门科目的学生,请说“数据库101”。每条记录有一个主题,这是一个简单的查询:
从student_subject中选择student_number,其中subject ='Database 101'
(也许你想加入student_info表来获取他的名字等,但这在这里并不重要。)
但是每个记录中有10个主题,你必须写:
select student_number from student_subject where subject_1 = 'Database 101'
or subject_2 = 'Database 101'
or subject_3 = 'Database 101'
or subject_4 = 'Database 101'
or subject_5 = 'Database 101'
or subject_6 = 'Database 101'
or subject_7 = 'Database 101'
or subject_8 = 'Database 101'
or subject_9 = 'Database 101'
or subject_10 = 'Database 101'
不仅打字很多,而且现在输入打字错误的几率是10倍。测试将不太可靠。假设您在subject_7的测试中错误输入了主题名称。该程序似乎可行:它会找到有1,2,3等课程的学生。如果碰巧没有考试中的学生将这个特定科目作为#7,那么该程序将给出正确的结果。我碰到了这一次:有人用category_1,category_2等创建了一个记录(我们把技术库中的书放入类别中),然后编写了一个查询,他在category_7的测试中输入了错误。在我们的测试中,我们通常只在每本书中放入2或3个类别,所以这一切似乎都有效。然后我们去了制作,并且在第一次有人拿出一本包含7个类别的书时失败了。
如果你必须编写检查所有10个字段的查询,那么如果有一天你需要添加一个字段,你必须找到每个查询并更新到测试#11。如果你错过了一个,你将开始在程序中得到微妙的错误。哦,我曾经遇到过这种情况。我们有一个数据库,我认为它是5个东西,并且有人写了一个查询,错误地,他测试了1,2,4和5,只是忘了测试#3。
如果您希望能够搜索主题,则需要10个字段的索引而不是1个。数据库开销要多得多。
如果我再考虑一下,可能还有其他原因。
答案 1 :(得分:2)
有一件事我想区别于Jay关于规范化的答案......为学生和科目分成两个表格。
不需要复制班级的名称,而且每个学生都要反复学习它的课程,它也应该是ONCE,然后是每个学生和课程的桥梁(或链接)表格。从这张表中你还可以获得通过/失败/成绩/撤回等状态......甚至是学期,等等。
此外,pk / fk列我尝试始终以“ID”与“_number”为后缀,这可能会让某些人感到困惑
Table Courses
courseID (PK) - auto-increment
course ex: ENGLISH, SCIENCE, COMPUTERS (or their abbreviated codes ENG-101, SCI-210, CMP-101)
Other any other description about the individual class -- REGARDLESS of when it was offered
Table StudentCourses
studentcourseid (PK)
student_number (FK to student table)
courseID (FK to course table)
enrollStatus (enrolled, withdrawn, excused, whatever)
enrollSemester (ex: SPRING2014, SUMMER2014, but this too could be a lookup table of semesters)
creditHoursEarned (such as for computing GPA)
这实际上是我在90年代中期写回的实际大学入学系统的简短简化,并在我离开该组织的2005年左右开始。
答案 2 :(得分:1)
规范化重新排列基本关系并加入依赖关系。 (某些连接依赖项对应于函数依赖项,确定候选键。)我们还可以在规范化时同时重新排列包含依赖项。 (候选键和包含依赖项确定外键。)因此,学习“连接依赖”,“功能依赖”和“候选键”的含义。对于你的ps,“包含依赖”。然后给我们您适用的JD,FD和CK(以及IND)。否则你的问题是无法回答的。
@others:规范化涉及重新排列模式,因此唯一的JD是CK的结果。 (非正式地,摆脱基本成员资格条件中的所有合取/意义而不是“attribute = foo(key)”形式。)(而且,PK没有正式的关系角色。)因此,数字后缀属性的猜测含义有没有关系到正常化,尽管由于其他原因设计不好(正如Mike Sherrill的'Cat Recall'所说)。