第一范式很简单不说了。
第二范式:
说白了即识别出业务中的对象,为每个对象定义一个数据库表。
比如拿学校模型举例。老师信息表,学生信息表,班级信息表...。每个表都有一个ID做为主键,其他字段记录着该对象的基本信息。
1 老师表(School_TeacherTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_TeacherTab')
DROP TABLE School_TeacherTab
CREATE TABLE dbo.School_TeacherTab(
School_TeacherTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_TeacherName VARCHAR(100) NOT NULL DEFAULT ''
);
2 学生表(School_StudentTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_StudentTab')
DROP TABLE School_StudentTab
CREATE TABLE dbo.School_StudentTab(
School_StudentTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_StudentName VARCHAR(100) NOT NULL DEFAULT ''
);
第三范式:
讲述的是表与表之间的关系。
常见的表之间的关系,是一对多(多对一,反过来看)关系。
比如,一个老师可以教多个学生,一个学生只能有一个老师。比如,武林门派,一派掌门可以收很多弟子,但是一个人不能参加两个以上门派。这样限定的话,上面的学生表要修改为:
2 学生表(School_StudentTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_StudentTab')
DROP TABLE School_StudentTab
CREATE TABLE dbo.School_StudentTab(
School_StudentTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_TeacherTabID INT NOT NULL FOREIGN KEY REFERENCES School_TeacherTab(School_TeacherTabID),
School_StudentName VARCHAR(100) NOT NULL DEFAULT ''
);
上面的表定义,表示不同的School_StudentTabID,可以有相同的School_TeacherTabID,这样即表示出来学生和老师之间的多对一关系。
有时候一个表不只和另外一个表有关系,可能和另外多个表有关系。假设限定,每个弟子都只会使一门兵器,不同的弟子可能练的是同一门兵器。同样学生和使用兵器是多对一关系。
3 兵器表(School_WeaponTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_WeaponTab')
DROP TABLE School_WeaponTab
CREATE TABLE dbo.School_WeaponTab(
School_WeaponTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_WeaponName VARCHAR(100) NOT NULL DEFAULT ''
);
学生表就变成了如下的形式:
2 学生表(School_StudentTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_StudentTab')
DROP TABLE School_StudentTab
CREATE TABLE dbo.School_StudentTab(
School_StudentTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_TeacherTabID INT NOT NULL FOREIGN KEY REFERENCES School_TeacherTab(School_TeacherTabID),
School_WeaponTabID INT NOT NULL FOREIGN KEY REFERENCES School_WeaponTab(School_WeaponTabID),
School_StudentName VARCHAR(100) NOT NULL DEFAULT ''
);
第二范式,要求我们识别出弟子,老师,兵器这些对象,将它们分别定义成一个个表,如果上面的学生表里,保存的除了兵器表id,还保存了兵器名称,就违反了第二范式。
多对对关系:
假设学生和老师之间的关系是多对多的关系,比如郭靖既拜柯镇恶为师,又拜洪七公为师;而洪七公除了郭靖,还收黄蓉为弟子。
这种情况下,我们既不能在老师表里加学生外键,也不能在学生表里加老师外键。而是要新建立一张老师_学生关系表,这种表不同于上面的对象表(描述对象信息),它描述的是对象间的关系。
4 老师_学生表(School_TeacherStudentTab)
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'School_TeacherStudentTab')
DROP TABLE School_TeacherStudentTab
CREATE TABLE dbo.School_TeacherStudentTab(
School_TeacherStudentTabID INT IDENTITY NOT NULL PRIMARY KEY NONCLUSTERED,
School_TeacherTabID INT NOT NULL FOREIGN KEY REFERENCES School_TeacherTab(School_TeacherTabID),
School_StudentTabID INT NOT NULL FOREIGN KEY REFERENCES School_StudentTab(School_StudentTabID),
);