什么是数据库范式,为什么要反范式?

所谓数据库范式,其实就是数据库的设计上的一些规范:这些规范可以让数据库的设计更加简洁、清晰;同时也会更加好的可以保证一致性。
三个常用的范式:

·第一范式(1NF)是说,数据库表中的性的原子性的,要求性具有原子性,不可再被拆分;比如地址如果都细化拆分成省、市、区、街道、小区等等多个字段这就是符合第一范式的, 如果地址就是一个字段,那就不符合了。
·第二范式(2NF)是说,数据库表中的每个实例或记录必须可以被唯一地区分,说白了就是要有主键,其他的字段都依赖于主键。
·第三范式(3NF)是说,任何非主属性不依赖于其它非主属性,也就是说,非主键外的所有字段必须互不依赖

如果我们在做表结构设计的时候,完全遵守数据库三范式,确实可以避免一些写时异常,提升一些写入性能,但是同时也会丢失一些读取性能。
因为在遵守范式的数据库设计中,表中不能有任何冗余字段,这就使得查询的时候就会经常有多表关联查询,这无疑是比较耗时的。
于是就有了反范式化。所谓反范式化,是一种针对遵从设计范式的数据库的性能优化策略。
也就是说,反范式化不等于非范式化,反范式化一定发生在满足范式设计的基础之上。前者相当于先遵守所有规则,再进行局部调整。
比如我们可以在表中增加一些冗余字段,方便我们进行数据查询,而不再需要经常做多表join,但同时,这也会带来一个问题,那就是这些几余字段之间的一致性如何保证,这个问题本来在遵守范式的设计中是不会有的,一旦做了反范式,那就需要开发者自行解决了
反范式其实本质上是软件开发中一个比较典型的方案,那就是"用空间换时间",通过做一些数据冗余,来提升查询速度。
在互联网业务中,比较典型的就是数据量大,并发高,并目通常查询的频率要远高于写入的频率,所以适当的做一些反范式,通过做一些字段的几余,可以提升查询性能,降低响应时长,从而提升并发度。

### 数据库范式的定义 满足最低要求的范式是第一范式(1NF),在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般来说,数据库只需满足第三范式(3NF)就行了[^1]。 ### 进行反范式的原因 在需要极高查询性能的场景中,会使用反范式技术。常见的反范式技术及其优势如下: 1. **冗余字段**:例如订单表冗余用户姓名(原本只需 `user_id`),可以避免在查询订单时需要关联用户表来获取用户姓名,提高查询效率。示例代码如下: ```sql CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, user_name VARCHAR(50), -- 冗余字段 order_date DATETIME, amount DECIMAL(10,2) ); ``` 2. **计数器字段**:如商品表冗余评论数(避免每次 `COUNT` 计算),每次新增评论时更新该字段,避免在需要获取商品评论数时进行实时的 `COUNT` 操作,提升查询性能。示例代码如下: ```sql CREATE TABLE products ( product_id INT PRIMARY KEY, name VARCHAR(50), price DECIMAL(10,2), comment_count INT -- 每次新增评论时更新此字段 ); ``` 3. **派生字段**:像订单表冗余总金额(避免每次 `SUM` 计算),在插入或更新订单明细时同时计算并更新总金额字段,避免在查询订单总金额时进行 `SUM` 计算,加快查询速度。示例代码如下: ```sql CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, total_amount DECIMAL(10,2), -- 派生字段 status VARCHAR(20) ); ``` 4. **合并表**:将订单和订单项合并(减少 `JOIN` 操作),减少了表之间的连接操作,提高查询性能。示例代码如下: ```sql CREATE TABLE orders_with_items ( order_id INT, order_date DATETIME, user_id INT, product_id INT, product_name VARCHAR(50), -- 冗余 quantity INT, unit_price DECIMAL(10,2), subtotal DECIMAL(10,2) -- 冗余 ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值