第一范式

第一正规化(1NF)是资料库正规化所使用的正规形式。第一正规化是为了要排除重复群的出现,要求资料库的每一列的论域都是由不可分割的原子值组成;每个栏位的值都只能是单一值。1971年埃德加·科德提出了第一正规化。

不符合第一正规化的情况

重复群

重复群通常会出现在会计帐上,每一笔记录可能有不定个数的值。举例来说:

交易
顾客 日期 数量
Pete Monday 19.00 -28.20
Pete Wednesday -84.00
Sarah Friday 100.00 150.00 -40.00

“数量”就是所谓的重复群了,而在这种情况下这份资料就不符合第一正规化。想要消除重复群的话,只要把每笔记录都转化为单一记录即可:

交易
顾客 日期 数量
Pete Monday 19.00
Pete Monday -28.20
Pete Wednesday -84.00
Sarah Friday 100.00
Sarah Friday 150.00
Sarah Friday -40.00

缺乏唯一识别码

一样是在交易这个例子中,同一天同一个人买了同样的数量,这样的交易做了两次:

交易
顾客 日期 数量
Pete Monday 19.00
Pete Monday 19.00

如上所示,这两笔交易可以说是一模一样,也就是说如果只靠这些资料我们没有办法分辨这两笔记录。我们之所以说它不符合第一正规化,是因为上面这样的表示法欠缺一个唯一识别码,可以是一个栏位,也可以是一组栏位,而且可以保证在这个资料中唯一识别码不会重复出现。要将它正规化到符合第一正规化的原则只需要加入一个唯一识别码即可:

交易
交易 ID 顾客 日期 数量
1 Pete Monday 19.00
2 Pete Monday 19.00

关联式资料库的第一正规化的讨论

重复群(repeating group)是指含有多值的一个列。原子性(atomicity)的操作语义可以说如果关系数据库管理系统的类型系统允许的值,例如date类型、VARCHAR(20)类型。严格意义上,NULL违背了第一范式;通常把NULL理解为标记(marker),而不是值(value),用专门的函数、运算符去处理NULL。

第一范式意味着:表中没有重复的行、重复的列;不存在行序、列序。

从某个角度看来,不允许重复群的出现是关联式资料库表示资讯的方法,RDBMS 里资料表每一笔记录的每一个栏位都只能是单个的原子值。举例来说,如果定义了一个叫做 Favorite Number 的整数栏位,每一笔记录的 Favorite Number 这个栏位都只会是一个整数 (或是无);这也就是说,如果设定了主键的话,理论上不可能会有任何关联式资料库的资料表会违反第一正规化的原则。

不过就算是在这种情况下,还是可以设计出在骨子里违反第一正规化的资料表。最简单的方法就是把多个有意义的值编码过后存进一个栏位里,然后在资料表中用很多栏位来表达同一个事实。

单一栏位中有多个有意义的值

在单一栏位中存放多个值是违反第一正规化的做法,下面这个就是很好的例子,它把多个值用逗号分开来表示:

挑食列表
不喜欢的食物
Jim Liver, Goat's cheese
Alice Broccoli
Norman Pheasant, Liver, Peas

以这样的设计看来,想要知道有什么人不喜欢某样特定的东西是很不容易的。不过可以把这个资料表转化成下面这种符合第一正规化的型式:

挑食列表
不喜欢的食物
Jim Liver
Jim Goat's cheese
Alice Broccoli
Norman Pheasant
Norman Liver
Norman Peas

用很多栏位来表达同一个事实

在同一个资料表里用多个栏位来表达同一个事情也是违反第一正规化的:

个人资料
喜欢的颜色 不喜欢的食物 (1) 不喜欢的食物 (2) 不喜欢的食物 (3)
Jim Green Liver Goat's cheese
Alice Fuchsia Broccoli
Norman Blue Pheasant Liver Peas
Emily Yellow

就算我们能确定每个人不喜欢吃的食物最多不会超过三样,这还是一个很糟的设计。举例来说,我们想要知道所有不喜欢同一种食物的人的组合的话,这就不是件容易的事,因为食物有可能出现在任何一个栏位,也就是说每一次的查询都要去检查 9 (3 x 3) 组不同的栏位组合。

参见

参考文献

外部链接