数据库规范化 Normalization

数据库规范化 Normalization

一个数据库会包含很多张表,那么这些表要如何因应需求来做设计呢?该设计哪些表?该设计哪些字段?这两节会告诉大家。
数据库规范化(Normalization)是数据库设计的一个非常重要的基本概念,目的是要去除重复的数据,增加数据的一致性。实际的作法是会将重复的字段,抽出来变成另一个新的表。
规范化还分成一阶规范化、二阶规范化、三阶规范化、DK/NF规范化等等不同级别,一般来说我们的应用软件会做到二阶或三阶规范化。
让我们用实际的例子来看:假设我们要设计一个场景是纪录「使用者 User」参与多个「活动 Event」

未规范化

image.png

这种 Table 设计缺点很多:
ihower 如果需要参加第四个活动,就必须变更 Table 的 Schema 增加更多字段。但是变更 Schema 是一件成本很高的事情 :(
john 没有参加这么多活动,多馀的字段都是 NULL,对数据库来说是浪费空间
ihower 跟 john 都有参加 RubyConf,但是 2015/9/11 这个活动日期重复存了。而且如果活动改日期,表示这些值都要改

一阶: 移除重复语意的 columns

刚刚的 event 1, event 1 date, event 2, event 2 date, event 3, event 3 date 俩俩都是重复的,让我们消灭它们:

image.png

缺点:
相比于没有规范化的,现在新报名不需要修改 Schame 了
但是重复的资料更多,包括用户数据和活动数据

二阶: 移除重复语意的 row

接下来需要拆表了,一口气我们拆成三张表:users 表、events 表、registration 表,并且 users 和 events 要加上可识别的 id 字段。
相信对 Rails 已经很熟悉的同学,这就是 User model 和 Event model 透过 Registration model 来达成多对多关系。

image.png

这好多了,看起来没有重复的资料了,如果要改 user 或 event 的数据,只需要改一个地方。
但是还有一个小地方可以改进,让我们继续看下去:

三阶: 移除不依赖主 ID 的资料

在 users table 中,city 名字其实只跟 zipcode 相关,跟 user id 没关系,因此这个 city 可以拆出来。在 users table 中只需要留着 zipcode 就好了。

image.png

小结
规范化让数据不会重复和高度一致性,节省空间、增加修改数据时的效率、避免数据不一致的错误。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。