阅读 222

Mysql 范式与反范式

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

猫和老鼠.jpg

前言:   本篇文章 是我关于MySQL的第28篇文章,水平一般、能力有限。文章写的比较浅,适合新手来看。

反范式

首先我们看一个例子:

街上新开了一家面馆,面馆有汤面和炒面。汤面统一价格是13元,炒面统一价格是15元。汤面里有牛肉拉面,西红柿鸡丝面。炒面有蛋炒面和尖椒炒面。我们来设计一份表。

CREATE TABLE `noodle` (
  `name` varchar(100) NOT NULL COMMENT '名称',
  `type` varchar(100) NOT NULL COMMENT '种类',
  `price` int NOT NULL COMMENT '价格'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='拉面信息';


select * from noodle;

name |type|price|
-----+----+-----+
蛋炒面  |炒面  |   15|
尖椒炒面 |炒面  |   15|
牛肉面  |汤面  |   13|
鸡蛋肉丝面|汤面  |   13|
复制代码

上面这种设计形式就是反范式,其将包含有传递数据的所有数据都写在一张表中。简单直接。 我们可以直观的看到 名称-种类-价格之间的关联关系。但是有冗余数据不可避免。

范式

还是上面的例子,我们直接来设计表结构。这次将传递数据分离开来。

CREATE TABLE `noodle` (
  `name` varchar(100) NOT NULL COMMENT '名称',
  `type` varchar(100) NOT NULL COMMENT '种类',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='拉面信息';
CREATE TABLE `noodle_type` (
  `type` varchar(100) NOT NULL COMMENT '种类',
  `price` int NOT NULL COMMENT '价格'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='拉面种类信息';

select * from noodle;

name |type|
-----+----+
蛋炒面  |炒面  |
尖椒炒面 |炒面  | 
牛肉面  |汤面  |  
鸡蛋肉丝面|汤面  |  

select * from noodle_type;

name |type|price|
-----+----+-----+
炒面  |   15|
汤面  |   13|

复制代码

上面这种设计形式就是范式,每张表都是单独的。没有冗余数据和传递依赖。每次修改炒面价格的时候只需要修改type表。而不是像反范式一样修改每一行炒面的价格。

总结

设计数据库表时,一定要灵活。没必要将所有表都拆的零碎。但是也没必要将所有的数据都写到一张表中,几十列反而不方便查询数据。将范式和反范式相结合才是最好的设计方式。

文章分类
后端
文章标签