有关数据库规范化的其他信息

时间:2014-02-25 17:25:14

标签: mysql sql database database-design database-normalization

我对规范化有点困惑。

有人可以在这个数据库中提供真实的例子吗?如果那没关系?谢谢。

  

表: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

  

关于外键,我可以在上面的给定表中使用它吗?

何时何地是使用它的最佳时间?

3 个答案:

答案 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,它只是一个序列号。

这样做有很多充分的理由。

  1. 10个科目是绝对限制,永远不可能改变吗?如果没有,如果有一天学生出现了11个科目,那么你的课程将会中断。我遇到过这个系统曾经遇到过的问题,我认为这是“儿童”的8个插槽。我想有人说,“谁会有超过8个孩子?”然后当然有人有11个孩子。

  2. 假设您要搜索所有正在学习某门科目的学生,请说“数据库101”。每条记录有一个主题,这是一个简单的查询:

    从student_subject中选择student_number,其中subject ='Database 101'

  3. (也许你想加入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个类别的书时失败了。

    1. 如果你必须编写检查所有10个字段的查询,那么如果有一天你需要添加一个字段,你必须找到每个查询并更新到测试#11。如果你错过了一个,你将开始在程序中得到微妙的错误。哦,我曾经遇到过这种情况。我们有一个数据库,我认为它是5个东西,并且有人写了一个查询,错误地,他测试了1,2,4和5,只是忘了测试#3。

    2. 如果您希望能够搜索主题,则需要10个字段的索引而不是1个。数据库开销要多得多。

    3. 如果我再考虑一下,可能还有其他原因。

答案 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'所说)。