假设有一个关系 R(A, B, C, D),并且已知以下函数依赖: A → B B → C BC → D 求候选键? 求候选码? 候选键/候选码 是同一个概念.
数据库范式也分为1NF,2NF,3NF,BCNF,4NF,5NF。
https://cloud.tencent.com/developer/article/2055118
2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖
3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖
一般在我们设计关系型数据库的时候,最多考虑到BCNF就够
https://www.cnblogs.com/xinaixia/p/4384353.html
第一范式(1NF)是关系数据库设计中的基本规范之一,确保数据库表的结构是原子的,不包含重复的组或集合。具体来说,1NF 要求:
- 每个表格单元格必须是原子性的:这意味着每个表格中的每个字段只能包含单一的值,而不能是多个值的集合。如果一个字段包含多个值,需要将其拆分成多个单独的字段。
举例来说,假设我们有一个存储学生信息的表格,如果表格设计如下:
学生ID | 姓名 | 电话号码 |
---|---|---|
1 | 小明 | 1234567890, 9876543210 |
在这个例子中,电话号码这一字段包含了两个值,使用逗号分隔。这不符合第一范式的要求,因为电话号码应该是一个原子的数据单元。要符合第一范式,应该将这个表格重构如下:
学生ID | 姓名 | 电话号码1 | 电话号码2 |
---|---|---|---|
1 | 小明 | 1234567890 | 9876543210 |
在重构后的表格中,每个电话号码现在都位于自己的字段中,每个字段只包含一个值,符合第一范式的要求。
总结来说,第一范式强调每个字段必须是原子性的,不可再分,不包含集合或者多个值,以确保数据库表的结构清晰、规范化,便于数据的管理和查询
第二范式(Second Normal Form, 2NF)是对第一范式(1NF)的一个扩展,要求关系模式除了满足1NF(即表中的每个字段都是不可分割的基本数据项)之外,还要满足非主属性对码不存在部分函数依赖。简单来说,就是确保表中的每一个非主属性都完全依赖于整个主键,而不是主键的一部分示例说明:
假设我们有一个订单管理系统的简单订单表,最初设计如下,不满足2NF:CREATE TABLE Orders (OrderID INT PRIMARY KEY,CustomerName VARCHAR(100),CustomerAddress VARCHAR(200),ProductID INT,Quantity INT,Price DECIMAL(10, 2)
);在这个表中,OrderID 是主键,用于唯一标识每个订单。但是,存在部分函数依赖,因为CustomerName和CustomerAddress只依赖于OrderID的一部分潜在含义——即客户信息,而实际上每个订单可能属于同一个客户,这样就导致了数据冗余。如果一个客户有多份订单,那么这个客户的姓名和地址就会在表中重复存储多次。
调整至2NF:
为了满足2NF,我们需要消除这种部分函数依赖,将表拆分为两个,确保每个非主属性都完全依赖于主键。
订单表(Orders):
CREATE TABLE Orders (OrderID INT PRIMARY KEY,CustomerID INT,ProductID INT,Quantity INT,Price DECIMAL(10, 2),FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
);客户表(Customers):
CREATE TABLE Customers (CustomerID INT PRIMARY KEY,CustomerName VARCHAR(100),CustomerAddress VARCHAR(200)
);
现在,Orders 表中的CustomerID引用了Customers表的主键,这样就消除了部分函数依赖。每个客户的信息只存储一次,无论他们有多少个订单,这不仅减少了数据冗余,也提高了数据的一致性和更新效率。这就是一个典型的将关系模式从1NF转换到2NF的例子。第三范式(Third Normal Form, 3NF)是在第二范式(2NF)的基础上进一步消除非主属性对码的传递函数依赖。也就是说,在一个满足3NF的关系中,除了主键以外的任何属性都不依赖于其他非主属性,仅依赖于主键。示例说明:
假设我们有一个学校数据库的初始设计,记录了学生、课程和教师的信息,设计了一个表来表示学生选课情况,但这个表不满足3NFCREATE TABLE Student_Course_Teacher (StudentID INT,CourseID INT,TeacherID INT,CourseName VARCHAR(100),TeacherName VARCHAR(100),PRIMARY KEY (StudentID, CourseID)
);在这个表中,主键是由StudentID和CourseID组成的复合键,用来唯一标识学生选修的每门课程。但是,存在传递函数依赖:TeacherName依赖于TeacherID,
而TeacherID又通过CourseID间接依赖于主键(因为每个课程只有一位授课教师)。此外,CourseName依赖于CourseID,同样构成了传递函数依赖。
调整至3NF:
为了满足3NF,我们需要消除这些传递函数依赖,将表拆分成更小的、更专注的表,确保每个非主属性直接依赖于主键,而不是通过其他非主属性间接依赖。
学生选课表(Student_Course):
CREATE TABLE Student_Course (StudentID INT,CourseID INT,PRIMARY KEY (StudentID, CourseID),FOREIGN KEY (StudentID) REFERENCES Students(StudentID),FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
);课程表(Courses):
CREATE TABLE Courses (CourseID INT PRIMARY KEY,CourseName VARCHAR(100),TeacherID INT,FOREIGN KEY (TeacherID) REFERENCES Teachers(TeacherID)
);教师表(Teachers):
CREATE TABLE Teachers (TeacherID INT PRIMARY KEY,TeacherName VARCHAR(100)
);
BCNF(Boyce-Codd Normal Form)是数据库规范化理论中的一种更高级别的范式,它是对第三范式(3NF)的进一步要求。BCNF 要求除了满足第三范式的所有条件外,还要求每一个确定关系的属性都与其所有候选关键字有关。简单来说,如果一个关系表中的所有非平凡函数依赖都是在候选关键字上的,则该关系表满足BCNF。
让我们通过一个例子来说明 BCNF 的概念和应用:
假设我们有一个关系表格存储员工的信息,其中包括员工号(EmployeeID)、姓名(Name)、部门号(DepartmentID)、部门名称(DepartmentName)等属性。
EmployeeID | Name | DepartmentID | DepartmentName |
---|---|---|---|
1 | Alice | 101 | HR |
2 | Bob | 102 | Finance |
3 | Charlie | 101 | HR |
在这个表格中,候选关键字可能是 {EmployeeID} 或 {EmployeeID, DepartmentID},因为 EmployeeID 是唯一标识一个员工,而 {EmployeeID, DepartmentID} 可能唯一标识一个部门内的员工。
现在,让我们检查该表是否符合 BCNF:
-
属性函数依赖分析:
- 假设我们有以下函数依赖:
- EmployeeID → Name (每个 EmployeeID 对应唯一的 Name)
- DepartmentID → DepartmentName (每个 DepartmentID 对应唯一的 DepartmentName)
- EmployeeID, DepartmentID → DepartmentName (每个员工在一个部门中有一个特定的部门名称)
- 假设我们有以下函数依赖:
-
确定关系:
- 候选关键字可以是 {EmployeeID} 或 {EmployeeID, DepartmentID}。
-
检查是否满足 BCNF:
- 现在我们来看,每个非平凡函数依赖是否都是在候选关键字上的。
- 对于函数依赖 EmployeeID, DepartmentID → DepartmentName,我们可以看到 EmployeeID 和 DepartmentID 一起确定了 DepartmentName,因此这个函数依赖满足 BCNF 的要求。
因此,这个表格满足 BCNF 的要求,因为所有非平凡函数依赖都是在候选关键字上的。这保证了表格结构的规范化,避免了数据冗余和插入异常,并且确保了数据的一致性和完整性。
自己的软考软件设计师笔记总结_后端_佳捷-开放原子开发者工作坊