数据库就像是一个巨大的文件柜,用来存储很多信息。这些信息被组织成很多小表格。而在数据库的世界里,我们有一些规则来确保这些表格整齐、有序,不会乱七八糟。这些规则就叫做范式。
范式就像我们要求字写得工整、清晰、有条理一样,是一种让数据库变得更加规范和整洁的方法。范式有很多级别,每个级别都有自己的标准和要求。
比如,我们有一张学生表,其中一个字段是地址。如果我们把地址拆分成省份、城市、街道、门牌号等多个字段存储,那么这就不符合第一范式的要求了,因为地址被分解成了多个部分,不再是原子性的了。正确的做法是把地址作为一个属性,存储为一个完整的字符串。
函数依赖是指在一个关系中,一个或多个属性的值可以唯一地决定另一个属性的值。就像我们在算数中,如果我们知道了某些数字的值,就可以唯一地确定另一个数字的值。
举个例子,假设我们有一个学生表,其中包括学生姓名、年龄、班级、学号等字段。我们可以发现,一个学生的学号是唯一的,并且可以唯一地确定该学生的姓名、年龄、班级等信息。而反过来,如果我们只知道一个学生的姓名、年龄、班级等信息,就无法唯一地确定该学生的学号。因此,学号函数依赖于姓名、年龄、班级等属性。
完全函数依赖是指在一个关系中,一个或多个属性的值可以唯一地决定另一个属性的值,且这个属性不依赖于任何一个属性的真子集。我们可以通过一个简单的例子来解释:
假设我们有一个班级表,其中包括学号、姓名、性别、年龄、班级、电话等字段。我们可以发现,一个学生的电话号码可以唯一地确定该学生的信息,包括姓名、性别、年龄、班级等。而反过来,如果我们只知道一个学生的姓名、性别、年龄、班级等信息,就无法唯一地确定该学生的电话号码。但是,如果我们知道了该学生的学号,就可以唯一地确定该学生的电话号码。这就是一个完全函数依赖关系,因为电话号码只依赖于学号这个属性,而不依赖于任何一个属性的真子集。
部分函数依赖是指在一个关系中,一个或多个属性的值可以唯一地决定另一个属性的值,但是这个属性还依赖于其他属性。我们可以通过一个简单的例子来解释:
假设我们有一个订单表,其中包括订单号、客户名称、客户地址、产品名称、数量、单价等字段。我们可以发现,一个订单的客户地址可以唯一地确定该订单的客户名称,但是客户名称还依赖于客户地址和其他属性,比如邮编等。这就是一个部分函数依赖关系,因为客户名称既依赖于客户地址这个属性,又依赖于其他属性。
比如,我们有一张学生成绩表,其中包括学生姓名、课程名称、成绩等字段。如果我们把学生姓名和课程名称合并成一个复合主键,那么成绩就不完全依赖于主键了,因为成绩既依赖于学生姓名,又依赖于课程名称。正确的做法是把学生姓名和课程名称分别作为主键和外键,成绩作为非主键属性。
比如,我们有一张订单表,其中包括订单号、客户名称、产品名称、数量、单价等字段。如果我们在表中存储了订单总价这个计算属性,那么它就不符合第三范式的要求了,因为订单总价依赖于数量和单价两个非主键属性。正确的做法是将订单总价作为一个视图或者计算字段来展示,不存储在表中。
比如,我们有一张部门表和员工表,其中部门表的主键是部门编号,员工表的主键是员工编号,部门表和员工表之间通过部门编号建立了关联。如果我们在员工表中存储部门名称这个属性,那么它就不符合第四范式的要求了,因为部门名称与主键部门编号只是间接相关,并不直接相关。正确的做法是在查询时将部门名称通过关联查询获得,而不是存储在员工表中。