CodeGym /课程 /SQL SELF /规范化的优缺点

规范化的优缺点

SQL SELF
第 26 级 , 课程 4
可用

今天我们再来聊聊一个很重要的话题:规范化的优点和缺点,这次会讲得更细一点,让你更清楚这些概念在实际开发中是怎么用的。好了,系好安全带——我们开始吧!

消除数据冗余

当表里的数据没规范化时,你会发现同样的信息会在不同的行里重复出现。比如,一个订单表里,每个订单都可能有重复的客户地址。规范化就是把这些重复的数据拆出来,放到单独的表里。

例子:

-- 规范化前
CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_name TEXT,
    customer_address TEXT,
    order_date DATE
);

-- 规范化后
CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    customer_name TEXT,
    customer_address TEXT
);

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id),
    order_date DATE
);

为什么这很重要?数据重复少了,出错的机会也就少了。如果客户地址变了,你只需要在一个地方更新数据就行。

保证数据完整性

当数据被拆分到不同的逻辑表里,管理它们之间的关系就很方便了。用外键可以自动帮你维护数据完整性。比如,你不会不小心删掉一个还被订单表引用的客户。

例子:

-- 外键保证删除客户时也会删掉相关订单
ALTER TABLE orders
ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE;

你可以放心,数据库结构不会让“孤儿”数据出现。

简化更新操作

当你的数据库规范化后,更新数据就变得简单又不容易出错。还是拿客户举例——如果客户换了地址,你只需要在一个表里改一次。在没规范化的表里,你很可能会忘了改某些行,导致数据不一致。

减少异常

插入异常:在没规范化的表里,有时候你没法插入一条记录,因为缺少一些没必要的信息。比如,客户名字不知道时就不能加订单。

更新异常:更新数据时可能会出错。比如,你只改了一行的客户名,别的行还是旧的。

删除异常:删除一条记录可能会导致丢失重要信息。比如,删掉一个订单时,如果客户名和订单在一个表里,客户名也会被删掉。

减少数据量

规范化通常能让数据库变小,因为去掉了重复数据。这个对存储大量信息来说很重要。

规范化的缺点

1. 数据库结构变复杂

时间久了,规范化可能让数据库结构变得很复杂,有成千上万张表。以前一张表能查到的数据,现在要写很复杂的 SQL 查询,还得用很多 JOIN

复杂例子:

-- 查询订单及商品和分类详情
SELECT
    o.order_id,
    o.order_date,
    c.customer_name,
    p.product_name,
    cat.category_name,
    oi.quantity,
    oi.unit_price
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
JOIN categories cat ON p.category_id = cat.category_id;

如果表和关系越来越多,查询的速度可能会变慢很多。

2. 频繁 JOIN 会影响性能

经常 JOIN 表(JOIN)会很耗资源,特别是表很大又没索引的时候。在分析型系统里,查询要处理几百万行,规范化会让性能大打折扣。

3. 需要额外操作来反规范化

如果规范化的数据库结构用来做分析,有时候得临时反规范化一下,才能让分析查询更快。这可能需要建视图(VIEW)或者聚合数据的表。

例子:

-- 用于分析的反规范化视图
CREATE VIEW orders_with_customers AS
SELECT
    o.order_id,
    o.order_date,
    c.customer_name,
    c.customer_address
FROM
    orders o
JOIN
    customers c ON o.customer_id = c.customer_id;

4. 入门门槛高

对新手来说,规范化看起来挺难的。不像一张表啥都有,现在得操作好几张表,还得搞清楚它们之间的关系。如果团队数据库水平不高,开发速度会被拖慢。

5. 有时候冗余反而有用

实际项目里,有时候保留冗余数据反而能提升性能。比如,应用经常用到某些只能通过复杂 JOIN 得到的数据,那还不如直接放一张表里。

1
调查/小测验
现有数据库分析第 26 级,课程 4
不可用
现有数据库分析
现有数据库分析
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION