数据库范式说明

数据库设计

前言

中国计算机学会副理事长-王珊教授的《数据库系统概论》

范式是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度

范式定义

一张数据表的表结构所符合的某种设计标准的级别

就像家里装修买建材,最环保的是E0级,其次是E1级,还有E2级等等。数据库范式也分为1NF ,2NF,3NF,BCNF,4NF,5NF。

意义:

范式是为了消除重复数据减少冗余数据,从而让数据库内的数据更好的组织

特点:

符合高一级范式的设计,必定符合低一级范式,例如符合2NF的关系模式,必定符合1NF。

第一范式

1NF:字段是最小的单元不可再分
地址表:
错:

id联系人联系地址
1野哥北京市朝阳区农光里211号 15555555555

有点对:

id联系人联系人电话联系人地址
1野哥1555555555北京市朝阳区农光里211号

非常对:

id联系人联系人电话地址
1野哥1555555555北京北京朝阳区农光里211号

疑问?仅仅符合第一范式是否就可以了

商品id商品名称分类号分类名价格仓库仓库负责人
1茜茜1双肩100A野哥
1茜茜2单肩80A野哥

更新异常:今天设计师想换个名字,叫 茜茜限量版, 工作人员要想着更新两次~

插入异常:设计部&市场部的矛盾;设计部新出了 茜茜6代, 但是价格还没定,给到电商人员录入,会出现 价格null的脏数据

综上 仅仅满足第一范式还是会出现问题~

第二范式

2NF:满足1NF,表中的字段必须完全依赖于全部主键而非部分主键

上表 主键【商品id&分类号】

如果只想获得分类名,已知分类号即可, 即产生部分依赖

所以修改成如下:

表1 商品表

商品id商品名称仓库仓库负责人
1茜茜Ayege

表2 分类表

分类id分类名
1双肩
2单肩

表3 定价表

商品id分类id价格
11100
1280

疑问: 修改仓库时,会不会有问题?

第三范式

3NF:满足2NF,非主键外的所有字段必须互不依赖,即非主键字段不能有传递性依赖

商品id -> 商品名称-> 仓库 -> 仓库负责人

仓库 - > 仓库负责人

原商品表拆分如下:

1,商品表

商品id商品名仓库
1茜茜A

2,仓库表

仓库仓库负责人
Ayege
B张三丰

反范式

必要的冗余可增加查询效率 【分类表记录 分类总销售数】

必要的冗余可以还原数据真实性 【订单 冗余地址详细信息】

### 数据库范式的概念 数据库范式是一种用于关系型数据库设计的原则,旨在减少数据冗余、提高数据一致性和可维护性。通过遵循这些原则,可以有效降低更新异常的风险,并使数据库结构更加清晰合理。 #### 第一范式 (1NF) 第一范式要求表中的每一列都必须是原子性的,即不可再分的数据项。这意味着每列只包含单一值,而不是一组值或复杂对象[^1]。 **示例:** 假设有一个学生选课记录表 `StudentCourses`: | StudentID | Name | Courses | |-----------|------------|--------------------------| | 1 | Alice | Math, Science | 这种设计违反了第一范式,因为 `Courses` 列包含了多个值。可以通过拆分为以下形式来满足第一范式: | StudentID | Name | Course | |-----------|--------|-----------| | 1 | Alice | Math | | 1 | Alice | Science | --- #### 第二范式 (2NF) 第二范式建立在第一范式的基础上,进一步要求消除部分依赖。具体来说,在一个表中,所有非主键字段必须完全依赖于整个主键,而不仅仅是其中的一部分[^1]。 **示例:** 考虑一张订单详情表 `OrderDetails`: | OrderID | ProductID | Quantity | CustomerName | |---------|-----------|----------|--------------| | 101 | P001 | 5 | John Doe | 在这个例子中,`CustomerName` 只依赖于 `OrderID` 而不依赖于 `(OrderID, ProductID)` 的组合主键。因此,该表不符合第二范式。解决方法是将其分解为两个独立的表: - **Orders 表** 存储订单及其客户信息 | OrderID | CustomerName | |---------|--------------| | 101 | John Doe | - **OrderItems 表** 记录每个订单的具体商品信息 | OrderID | ProductID | Quantity | |---------|-----------|----------| | 101 | P001 | 5 | --- #### 第三范式 (3NF) 第三范式是在第二范式基础上更严格的要求,它消除了传递依赖。也就是说,任何非主属性都不能间接依赖于其他非主属性。 **示例:** 继续以上面的例子扩展,如果我们在 `Products` 表中加入供应商名称,则可能出现如下情况: | ProductID | ProductName | SupplierName | SupplierAddress | |-----------|-------------|--------------|-----------------| | P001 | Laptop | ABC Corp | Street X | 这里存在一个问题:`SupplierAddress` 并不直接依赖于 `ProductID`,而是通过 `SupplierName` 进一步关联起来。这违背了第三范式。解决方案是对供应商信息单独建模: - **Suppliers 表** | SupplierName | SupplierAddress | |--------------|-----------------| | ABC Corp | Street X | - **Products 表** | ProductID | ProductName | SupplierName | |-----------|-------------|--------------| | P001 | Laptop | ABC Corp | --- ### 高级范式简介 除前三范式外,还有更高层次的设计标准,例如 BCNF 和第四范式(4NF),它们适用于更为复杂的场景。当涉及多值依赖或多关键字约束时,通常会引入这些高级范式[^2]。 #### Boyce-Codd 范式 (BCNF) BCNF 是对第三范式的补充和完善,解决了某些特殊情况下仍然存在的函数依赖问题。其核心在于确保所有的决定因素都是候选键[^2]。 #### 第四范式 (4NF) 第四范式主要针对多值依赖进行了优化,允许将具有相同父实体的不同子集分离到不同的表格中,从而避免重复存储相同的多值集合。 --- ### SQL 实现示例 以下是基于上述理论的一个简单实现案例: ```sql -- 创建 Suppliers 表 CREATE TABLE Suppliers ( SupplierName VARCHAR(50) PRIMARY KEY, SupplierAddress VARCHAR(100) ); -- 插入供应商数据 INSERT INTO Suppliers VALUES ('ABC Corp', 'Street X'); -- 创建 Products 表 CREATE TABLE Products ( ProductID INT PRIMARY KEY, ProductName VARCHAR(50), SupplierName VARCHAR(50), FOREIGN KEY (SupplierName) REFERENCES Suppliers(SupplierName) ); -- 插入产品数据 INSERT INTO Products VALUES (1, 'Laptop', 'ABC Corp'); ``` --- ### 总结 数据库范式的核心目标是通过规范化设计减少冗余和潜在错误风险,同时提升查询效率与系统稳定性。然而,在实际开发过程中也需要综合考量性能需求以及业务逻辑特点,灵活运用不同级别的范式规则[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YEGE学AI算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值