马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
数据库第三范式(3NF)终极指南
一、第三范式焦点原理
1.1 基本定义
在满意第二范式(2NF)的底子上,消除非主属性对候选键的转达依赖
1.2 关键概念剖析
- 转达依赖:若A→B且B→C,则称C转达依赖于A
- 直接依赖:非主属性必须直接依赖候选键
- 非主属性:不属于任何候选键的属性
1.3 违反3NF的典型场景
- 学生成绩表(不符合3NF)
- +----------+----------+--------+------------+-----------------+
- | 学号(PK) | 课程号(PK)| 成绩 | 学院名称 | 学院院长 |
- +----------+----------+--------+------------+-----------------+
- | 2023001 | C001 | 85 | 计算机学院 | 张伟民 |
- | 2023001 | C002 | 92 | 计算机学院 | 张伟民 |
- +----------+----------+--------+------------+-----------------+
复制代码 问题分析:
- 学院院长 → 学院名称 → 学号(转达依赖)
- 同一学院院长信息重复存储
二、企业级实战案例
2.1 电商订单系统优化
原始表结构:
- 订单表(不符合3NF)
- +----------+------------+-----------+------------+----------+---------------+
- | 订单号(PK)| 用户ID | 用户等级 | 商品ID(PK) | 商品价格 | 商品供应商 |
- +----------+------------+-----------+------------+----------+---------------+
- | O1001 | U8801 | VIP3 | P001 | 5999 | 苹果公司 |
- | O1001 | U8801 | VIP3 | P005 | 199 | 小米科技 |
- +----------+------------+-----------+------------+----------+---------------+
复制代码 规范化步骤:
- CREATE TABLE users (
- user_id VARCHAR(10) PRIMARY KEY,
- level VARCHAR(10) NOT NULL
- );
- CREATE TABLE user_levels (
- level VARCHAR(10) PRIMARY KEY,
- discount_rate DECIMAL(5,2)
- );
复制代码- CREATE TABLE suppliers (
- supplier_id VARCHAR(10) GENERATED ALWAYS AS (
- CASE
- WHEN supplier_name = '苹果公司' THEN 'S001'
- WHEN supplier_name = '小米科技' THEN 'S002'
- END
- ) STORED PRIMARY KEY,
- supplier_name VARCHAR(50) UNIQUE NOT NULL
- );
- CREATE TABLE products (
- product_id VARCHAR(10) PRIMARY KEY,
- price DECIMAL(10,2),
- supplier_id VARCHAR(10),
- FOREIGN KEY (supplier_id) REFERENCES suppliers(supplier_id)
- );
复制代码 2.2 人力资源管理系统改造
原始员工表:
- 员工表(不符合3NF)
- +----------+----------+------------+-----------+---------------+
- | 员工ID | 部门编号 | 部门名称 | 部门预算 | 部门所在地 |
- +----------+----------+------------+-----------+---------------+
- | E001 | D01 | 研发部 | 5000000 | 上海浦东 |
- | E002 | D02 | 市场部 | 3000000 | 北京朝阳 |
- +----------+----------+------------+-----------+---------------+
复制代码 规范化方案:
- -- 部门维度表
- CREATE TABLE departments (
- dept_id VARCHAR(10) PRIMARY KEY,
- dept_name VARCHAR(30) UNIQUE NOT NULL,
- budget DECIMAL(12,2),
- location VARCHAR(50)
- );
- -- 精简员工表
- CREATE TABLE employees (
- emp_id VARCHAR(10) PRIMARY KEY,
- dept_id VARCHAR(10),
- FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
- );
复制代码 三、依赖关系分析方法
3.1 函数依赖图谱
3.2 转达依赖判断公式
- 存在函数依赖:
- A → B → C
- 则:
- A → C 是传递依赖
- 当且仅当:
- B ↛ A(B不能决定A)
复制代码 3.3 典型转达依赖模式
依赖链问题类型办理方案学号 → 学院 → 院长信息重复创建学院维度表订单 → 客户 → 区域区域统计困难建立客户-区域映射表产物 → 类别 → 税率税率更新复杂单独税率设置表 四、性能优化平衡计谋
4.1 答应违反3NF的场景
场景示例优化方案及时盘算要求高订单总金额表现冗余存储金额字段数据堆栈维度表星型模型中的维度表适当生存冗余描述字段高频读取低频更新商品分类信息反规范化存储 4.2 索引优化方案
- -- 覆盖索引优化
- CREATE INDEX idx_emp_dept
- ON employees(dept_id) INCLUDE (emp_id);
- -- 函数索引优化
- CREATE INDEX idx_supplier_name
- ON suppliers(UPPER(supplier_name));
复制代码 五、实战练习题
题目1:改造图书借阅系统
- 借阅记录表(不符合3NF)
- +----------+----------+------------+------------------+---------------+
- | 借阅ID | 图书ID | 图书类别 | 读者ID | 读者单位 |
- +----------+----------+------------+------------------+---------------+
- | L2023001 | B001 | 计算机 | R002 | 清华大学 |
- | L2023002 | B005 | 文学 | R005 | 北京大学 |
- +----------+----------+------------+------------------+---------------+
复制代码 题目2:优化物流管理系统
- 运单表(不符合3NF)
- +----------+------------+--------------+----------------+---------------+
- | 运单号 | 快递公司 | 公司联系电话 | 收件人ID | 收件人所属省 |
- +----------+------------+--------------+----------------+---------------+
- | YD23001 | SF | 95338 | J23001 | 广东省 |
- | YD23002 | YTO | 95554 | J23005 | 浙江省 |
- +----------+------------+--------------+----------------+---------------+
复制代码 参考答案:
- -- 题目1解决方案
- CREATE TABLE books (
- book_id VARCHAR(10) PRIMARY KEY,
- category VARCHAR(20)
- );
- CREATE TABLE readers (
- reader_id VARCHAR(10) PRIMARY KEY,
- institution VARCHAR(50)
- );
- CREATE TABLE borrow_records (
- borrow_id VARCHAR(10) PRIMARY KEY,
- book_id VARCHAR(10),
- reader_id VARCHAR(10)
- );
- -- 题目2解决方案
- CREATE TABLE couriers (
- company_code VARCHAR(10) PRIMARY KEY,
- company_name VARCHAR(50),
- contact_tel VARCHAR(20)
- );
- CREATE TABLE recipients (
- recipient_id VARCHAR(10) PRIMARY KEY,
- province VARCHAR(20)
- );
- CREATE TABLE waybills (
- waybill_no VARCHAR(20) PRIMARY KEY,
- company_code VARCHAR(10),
- recipient_id VARCHAR(10)
- );
复制代码 六、扩展学习资源
6.1 保举工具
- Normalization Checker:在线范式验证工具(https://www.database-normalizer.com)
- pgAdmin:PostgreSQL的范式分析插件
6.2 经典文献
- 《Database System Concepts》第7章:关系数据库计划
- Microsoft SQL Server 最佳实践白皮书《Normalization Guidelines》
6.3 项目实战库
- GitHub堆栈:https://github.com/normalization-labs/3nf-examples
- Kaggle数据集:Amazon Sales Data(适合进行规范化练习)
6.4 视频课程
- Udemy《Database Design Fundamentals》第5章
- YouTube频道「TechTFQ」规范化专题(含实战演示)
七、常见错误排查指南
错误征象1:循环依赖
症状:
- 部门表:dept_id → manager_id
- 员工表:emp_id → dept_id
- 经理表:manager_id → emp_id
复制代码 办理方案:
- 冲破循环:在部分表中直接存储经理姓名
- 添加束缚:确保经理属于对应部分
错误征象2:过分规范化
症状:
- 简单的用户表被拆分成10个关联表
- 必要5次JOIN才能获取完备信息
办理方案:
- 归并低频变更字段
- 使用JSON字段存储扩展属性
错误征象3:忽略业务束缚
症状:
- 答应同一商品在差别订单中有差别代价
- 但业务要求代价必须同一
办理方案:
- ALTER TABLE order_details
- ADD CONSTRAINT price_consistency
- CHECK (price = (SELECT price FROM products WHERE product_id = order_details.product_id));
复制代码 八、范式演进与工程实践
8.1 现代数据库计划趋势
计划模式实用场景3NF应用微服务架构服务独立数据库在服务内保持3NF数据湖架构原始数据存储不逼迫规范化及时数仓流式数据处置惩罚适当反规范化 8.2 云原生数据库实践
- AWS Aurora:使用Read Replica处置惩罚规范化表的查询压力
- Google Spanner:在分布式数据库中实现参照完备性
- Azure CosmosDB:使用反规范化计划优化文档存储
九、企业口试重点
9.1 高频考题
- 解释什么是转达依赖?
- 如何证明一个表计划符合3NF?
- 什么时间应该故意违反第三范式?
9.2 参考答案示例
问题:订单表包含客户所在城市是否违反3NF?
回答:
- 如果存在 订单ID → 客户ID → 客户城市 的依赖链
- 且客户ID ↛ 订单ID(即客户可能有多笔订单)
- 则属于转达依赖,违反3NF
- 应拆分为客户信息表和订单表
十、下一步学习方向
学习建议:
- 使用DBngin搭建多版本数据库环境
- 在GitHub上寻找开源项目的数据库计划分析
- 尝试在MongoDB中实现关系型规范化
- 学习使用dbt(data build tool)进行数据建模
十一、综合应用寻衅
实战项目:计划跨境电商系统数据库
- 需求清单:
- 1. 支持多币种价格存储
- 2. 记录商品的多级分类
- 3. 跟踪供应商的所在国家/地区
- 4. 管理用户的跨境配送地址
复制代码 计划要点:
- 钱币汇率单独建表
- 商品分类使用闭包表计划
- 国家信息符合3NF标准
- 地点信息采用半结构化存储
- -- 示范代码片段
- CREATE TABLE countries (
- country_code CHAR(2) PRIMARY KEY,
- country_name VARCHAR(50) NOT NULL,
- currency_code CHAR(3) NOT NULL
- );
- CREATE TABLE exchange_rates (
- base_currency CHAR(3),
- target_currency CHAR(3),
- rate DECIMAL(12,6),
- PRIMARY KEY (base_currency, target_currency)
- );
- CREATE TABLE product_categories (
- category_id INT PRIMARY KEY,
- parent_id INT REFERENCES product_categories(category_id),
- category_name VARCHAR(50) NOT NULL
- );
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|