原则:
规范化的目的是一份数据只存储在一个地方。
根据上面的原则来理解3种范式:
第一范式:
列的原子性;
保证行的唯一性---一份数据只存储在一个地方。
第二范式:非属性键与主键的关系
1.满足第一范式
2.非键属性依赖于整体主键,而不是非键属性仅仅依赖于主键中的某个部分。即:无部分依赖:
违反第二范式就是存在部分依赖(非键属性仅仅依赖于主键中的某个部分)。
违反第二范式这有点像:
在一个由诸多长老全部举手表才能表决的组织里,你却只听一个或个别长老的话,这可是坏了规矩的。
例如,如下的关系就违背了第二范式:
关系名:PersonPet(人宠物)
主键:PesonId 、PetId
非键属性:PesonName、PetName、PetType
违背第二范式:PesonName只依赖于PesonId
PetName只依赖于PetId
举个例子,违反了第二范式存储的数据的样子:
PesonId PetId PesonName PetName
1 1 人才1 宠物1
2 2 人才2 宠物2
3 1 人才3 宠物1
在现实生活中,人和宠物的关系是多对多的关系,即:
1个人可以有0、1、1以上个宠物
1个宠物可以属于0(如流浪狗)、1(单身IT男)、1个以上(一对情侣)个人
我们从上表因为违反第二范式而存储的数据违反规范化的原则:
规范化的目的是一份数据只存储在一个地方。
即:PetId为1的宠物,在存储数据的时候,被复制了多次,存放的不同的地方。
这样会对数据的增、删、改。会有什么影响:
增:
1.通常来说,当需要对单个事物(单个人、单个宠物)进行处理,而不是处理他们之间关系时,
因为没有专门为“人”这个实体建立了的表(如:Person表)为了增加一个人,不得不在PersonPet(人宠物表)中添加人
的相关信息,而在“宠物”相关的列输入无意义的值。
在单独查询人(不查询宠物)的时,不得不额外去除掉那些来自宠物相关信息。
2.只要一个人有多个宠物,这个人的信息将被多次复制。同样:
3.只要一个宠物属于多个人,这个宠物的信息也将被多少复制。
删:
当需要对单个事物(单个人、单个宠物)进行处理,而不是处理他们之间关系时,对删除的影响:
如果PesonId为1和3(这对情侣可能同时出现车祸)的人都没,要删除这两个人,存储的数据就是这样的:
PesonId PetId PesonName PetName
NULL 1 NULL 宠物1
2 2 人才2 宠物2
NULL 1 NULL 宠物1
可以看到这样的设计基本废掉了。
改:
数据同步问题, 例如:通过主键(PesonId ,PetId)=(1,1)修改 PetName的值“宠物1”为“宠物007”,如果在编程时没有
注意同步
PesonId PetId PesonName PetName
3 1 人才3 宠物1
那么就破坏了数据。
第三范式:非属性键之间的关系
1.满足第二范式
2.非属性键不依赖于非属性键,即:不存在传递依赖。
违反第三范式这有点像:
在朝廷中有个皇帝(主键)就够了,有人结党私营,搞小团体,听命于一个小头目(非属性键依赖于非属性键),也是坏了规矩的。
Book表
主键:BookIsbnNunmber
非属性键:Title
Price
PublishName
PublishCity
这个表满足了第二范式.
但是违反了第三范式:
非属性键PublishCity依赖于非属性键PublishName。
违反了第三范式将导致如下问题,例如下面违反了第三范式的表存储的数据:
BookIsbnNunmber Title Price PublishName PublishCity
1001 《我是人才》 63.1 人才出版社 地球村
1002 《我是蠢材》 87.2 人才出版社 地球村
按常规,我们都是通过“主键”去唯一定位要修改的数据,所以,用如下SQL语句:
Update adb.Book
Set PublishCity='月亮城'
Where BookIsbnNunmber=‘1001’;
执行以上SQL后,表中的数据如下:
BookIsbnNunmber Title Price PublishName PublishCity
1001 《我是人才》 63.1 人才出版社 月亮城
1002 《我是蠢材》 87.2 人才出版社 地球村
这就产生了数据同步的问题,数据在更新时被破坏了。
PublishName PublishCity
人才出版社 月亮城
人才出版社 地球村
由于违反了第三范式(非属性键PublishCity依赖于非属性键PublishName),
我们就得写额外的处理去更新所有列的PublishName
Update adb.Book
Set PublishCity='月亮城'
Where PublishCity='地球村' And PublishName='人才出版社'
这样,说明一点,违反第三范式,为了更细数据时,避免非属性键之间依赖产生的数据同步问题,不得不
进行而不处理数据同步问题,但是这额外的同步数据操作很容易被忘记,
更糟糕的是,系统的关系会随着时间的关系不断变化,你也将越来越头痛。