关系数据库中的范式建模

范式(normal form),我的理解是用来规范关系数据库中实体如何划分以及实体间如何建立联系来保持数据完整性的一种指导思想,目的就是要消除数据冗余,追求单表操作,修改某个实体只需要操作一张表,实体与实体间修改互不影响。目前存在六种范式:1NF/2NF/3NF/BCNF/4NF/5NF,它们之间属于层层递进的关系。日常业务中满足3NF就可以了,因为更高的范式意味着更多层表的拆分,那么在操作时也就会产生更多的表关联,同样会拉低性能。

1NF
1NF用来保证属性的原子性。也就是属性不可再分。什么是原子性,我的理解是没有绝对的原子性,具体需要结合业务来设计。比如对于地址这个属性,如果业务中这个属性只是为了简单的对地址做个记录,我们可以直接设计成类似xx省xx市xx县”,而如果在以后的业务中可能会发生针对于市县的操作,那就需要对地址进行到市县的分解。1NF是关系型数据库的基础,不满足1NF就不是一个关系型数据库。

2NF
2NF的目的是消除部分依赖。指的是表中所有除主键外的属性都能由这个主键唯一确定,不能由这个主键中的部分字段确定。举个例子,有学生成绩表(学号,课程,姓名,成绩),这个成绩表中主键是(学号,课程),(学号,课程)作为主键时可以确定成绩。而对于姓名这个属性,只根据学号就可以确定。这里,就存在姓名对主键(学号,课程)的部分依赖。从这个例子可以看出,如果一个表存在部分依赖其实说明了这个表中至少存储了两种实体的数据,在这个例子中存储了成绩实体和学生实体的数据。

3NF
3NF用来消除传递依赖。直白说就是表中所有主键外的属性都得与主键直接相关,而不能是间接相关。比如有学生信息表(学号,姓名,院系,院系主任),其中主键为学号,根据学号可以确定院系,根据院系可以确定院系主任,这里就说存在院系主任对学号的传递依赖。其实这里还是说明一个表中如果存在传递依赖,也至少存储了两个实体类型的数据。个人觉得二范式和三范式的目的都是为了保证一张表只存储一种实体数据,减少数据冗余,保证数据的完整性。区别在于分表的过程,2NF是以复合主键中的主属性来建立两个实体之间的联系,保证实体完整性。而3NF是通过外键的形式建立两个实体之间的联系,保证参照完整性。

遵守3NF建模的好处
从上面可以看到,如果表的设计不满足2NF或3NF,那么就会存在一个表中包含多个实体属性的问题,造成数据冗余,这种数据冗余一方面导致数据修改复杂,另一方面可能会导致数据插入或删除时引起业务逻辑上的错误。

比如说对于2NF中的那个成绩表(学号,课程,姓名,成绩),一个学生每选一门课,他的姓名就会被存储一次,如果说某天这个学生改名了,那么所有他选过的课程记录都要被修改,不仅效率低,也容易漏改出错,这表现了修改复杂。再比如说,这个学生还没选课,那么就会因为缺少主键而保存不了学生实体的信息,这里存在插入异常。或者说是,这个学生开始选了2门课,后来因为不喜欢不选了,当这个学生所有的选课记录都被删除后,那么这个学生实体的信息也丢失了,这里就表现出删除异常。

实际业务中怎么遵守3NF建模

这里引用网上看到的一段话,觉得很精炼简洁:怎么做到第三范式? 不需要考虑第三范式的定义。按对象划分就好了,学生的属性归学生,系的属性归系,教师的属性归教师,学校的属性归学校。

### 使用传统数据库范式进行数据建模的最佳实践 #### 一、理解三范式的定义及其作用 为了确保数据库设计的有效性和高效性,在构建数据模型时遵循三范式是非常重要的。第一范式(1NF)规定表中的每一列都不可再分,即实现原子化;第二范式(2NF)要求非主键字段完全依赖于主键,消除部分函数依赖;第三范式(3NF)进一步去除传递依赖,使得所有非主属性只依赖于候选码。 #### 二、实际操作流程 当应用三范式来创建一个规范化的关系型数据库结构时,可以按照如下方式执行: - **识别实体与关系** 对业务逻辑进行全面分析,找出所有的实体对象以及它们之间的关联关系[^4]。这一步骤对于后续的数据表划分至关重要。 - **转换成表格形式** 将上述发现的每一个实体转化为一张独立的表,并为每张表指定唯一标识符作为主键。例如,在处理订单管理系统时,“客户”、“产品”和“订单详情”分别对应不同的表单。 - **满足第一范式 (1NF)** 确保每个字段都是单一值而非复合项或数组类型。如果存在多值情况,则应将其拆分为单独记录并引入外键连接至原表。比如,假设某位顾客可能拥有多个联系方式,那么应该新建联系人子表而不是在一个单元格内罗列全部电话号码[^5]。 - **达到第二范式 (2NF)** 基于已有的主键设置,检查是否存在任何仅由部分主键决定的信息片段。如果有这样的冗余数据,则应当分离出来形成新的派生表。以销售发票为例,其中的商品明细不应直接存放在总账目里,而是要另立商品清单表并通过共同的交易ID相联接。 - **符合第三范式 (3NF)** 接下来审视剩余的所有非关键字字段是否间接依赖其他非关键字元素。一旦确认此类现象发生——即使不是通过完整的主键路径——也得把有关条目提取出去构成辅助表。继续沿用之前的例子来说,假如商品名称会随时间变化而更新的话,就最好把它移到专门的产品档案中维护,从而避免重复修改影响整体性能。 ```sql CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50) ); CREATE TABLE Orders ( OrderID INT PRIMARY KEY, OrderDate DATE, TotalAmount DECIMAL(18, 2), CustomerID INT, FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ); CREATE TABLE Products ( ProductID INT PRIMARY KEY, Name VARCHAR(100), Price DECIMAL(18, 2) ); CREATE TABLE OrderDetails ( DetailID INT PRIMARY KEY, Quantity SMALLINT, UnitPrice DECIMAL(18, 2), OrderID INT, ProductID INT, FOREIGN KEY (OrderID) REFERENCES Orders(OrderID), FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值