一、数据冗余:存储空间浪费
问题表现:
相同数据在多个位置重复存储
更新时需要同步修改多处,易遗漏
案例:
未规范化的订单表(客户信息重复)
CREATE TABLE orders ( order_id INT, customer_name VARCHAR(50), -- 冗余 customer_phone VARCHAR(20), -- 冗余 product_name VARCHAR(50), -- 冗余 price DECIMAL(10,2) );
后果:
同一客户下100个订单 → 客户信息重复存储100次
客户修改电话时需更新所有相关订单
二、数据异常:破坏数据一致性
1. 插入异常
场景:无法插入部分必要数据
未拆分的课程表(学生必须选课才能记录课程信息)
CREATE TABLE student_courses ( student_id INT, course_id INT, course_name VARCHAR(50), -- 依赖course_id PRIMARY KEY (student_id, course_id) );
问题:
新课程无人选课时无法存入系统
2. 更新异常
场景:修改部分数据导致不一致
冗余存储的商品信息
UPDATE order_items SET product_name = '新款手机' WHERE product_id = 100; -- 可能漏改部分记录
结果:
同一商品在不同订单中显示不同名称
3. 删除异常
场景:删除数据时意外丢失信息
混合存储订单和客户信息
DELETE FROM orders WHERE customer_id = 123; -- 会同时删除客户信息
三、操作效率降低
典型问题:
1. 写入性能差:
更新冗余数据需多行操作(如修改客户地址需更新所有订单)
2. 查询复杂度高:
未拆分的大表导致全表扫描(如百万级订单包含重复客户信息)
对比实验:
操作类型 | 规范化设计耗时 | 非规范化设计耗时 |
---|---|---|
更新客户电话 | 1ms (单表) | 50ms (多表联动) |
查询订单详情 | 5ms (JOIN) | 2ms (单表) |
四、何时可以故意违反范式?
合理反范式场景:
1. 读多写少:商品销量计数器(高频查询,低频更新)
ALTER TABLE products ADD COLUMN sales_count INT; -- 冗余但提升查询性能
2. 历史快照:订单保留下单时的价格(与当前商品价格解耦)
3. 数据仓库:分析型系统允许适度冗余
五、自查清单:你的数据库是否面临风险?
1. 是否有字段存储多个值(违反1NF)?
2. 修改某个数据是否需要更新多行?
3. 删除数据时是否会意外丢失关联信息?
4. 是否有大量重复的文本数据(如相同的地址、描述)?
诊断工具:
查找可能冗余的字段(相同值出现多次)
SELECT customer_name, COUNT(*) FROM orders GROUP BY customer_name HAVING COUNT(*) > 5;
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程