【翻译】数据库设计——范式

简介

数据库所需要的特性是为了有效的存储以及容易维护数据

第一点,有效的存储是指应避免数据冗余;第二点,易于维护是指一个好的数据库设计是将数据有逻辑地分散在数据表中。

规范化是一种实现这些目的的数据库设计方法。

什么是规范化?

数据库规范化,又称数据库或资料库的正规化、标准化,是数据库设计中的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性。(wikipedia.com)

规范化提供了一系列原则来帮助:

  • 有效的组织数据
  • 减少数据冗余
  • 确保只有相关的数据被存储在一张表中

范式

随着时间的推移,已经发展出了一些好的规则,这些规则允许一个数据库被设计成具有不同程度的数据库。这些规则被称为范式,这些范式用0到5数字进行编号,即0NF,1NF,2NF,3NF,4NF,5NF。

在这里,你并不需要关心4NF和5NF,因为它们暂时在这里不做讨论。我们将只讨论1NF,2NF,3NF。

你应该知道范式是数据库设计者的唯一指导方针——但是他们并不一定要遵循它们!

You should be aware that normal forms are only guidelines for the database designer - they do not have to follow them!

数据库设计者根据需要开发的数据库类型来选择范式。他们也许不规范化他们的数据库,此时这种数据库被称为未规范化数据库或0NF。

第一范式-1NF

对于一个属于第一范式的数据库,数据库中的每一张表都必须符合下面的规则:

  • 没有重复的或相似数据的列
  • 每一项都不能再分割
  • 每一行都是唯一的,也就是说数据库有一个主码
  • 每一个域都有一个唯一的名字

原子性这个词用于描述一个数据项不可再分割的性质。

untitled.jpg

原子性数据示例

  • 身份证号码
  • 社会保险号
  • 书的ISBN编码,如1-931841-62-4
  • 股票代码
  • 一个人的姓
  • 一个人的名
  • 电话号码
  • 学校名字,如 'Abington Hall Comprehensive School'
  • 一个完整的说明,如'A fountain pen is a writing instrument'

最后的两个示例说明了原子性并不代表是一个单词。它只是简单的指当我们去除数据项中的某些字符时,它将会变得无法理解,因为它失去了原本的意思。

非原子性数据示例

  • 一个人的全名,如John Hunt,它实际包括了姓和名,一起存储在数据库
  • 一个完整的地址,如6 Picton Road, London, WR1 4PG,它实际包括了街道,城市等信息
  • 一个更大数据集的部分数据(Data that are part of a larger dataset),如Oxford Book club and Coventry Health club

重复数据示例

IDFirst nameSurnameTelePhone1TelePhone2TelePhone3
2TomSmith22323456343456345

在这种情况下,数据库尝试保存每一个人的多个号码。数据库设计者创建了三个域用于保存电话号码。这就是所谓的重复数据,电话号码属于同一种类型的数据。

1NF示例 1

提醒:第一范式规则

  • 没有重复的或相似数据的列
  • 每一项都不能再分割
  • 每一行都是唯一的,也就是说数据库有一个主码
  • 每一个域都有一个唯一的名字

下面哪个数据表不符合第一范式?

  1. TitleFirstnameSurnameFull nameAddressCity
    MrTomSmithTom Smith42 Mill StreetLondon
  2. ID[主码]IP Addressusernamelast accessedActivityResultactive
    1003[主码]198.168.1.5Smith20081021:14.10Save filesuccessy
  3. ItemID[主码]ProductDescriptionSizeColourColourColour
    234ShoeHigh Heel6redbluebrown
  4. StudentID[主码]FirstnameSurnameSchoolID*ClassID*
    354TomSmith65F

说明:

表一:不属于1NF,没有定义主码,因此每一条记录不能保证是唯一的。Full name 是冗余的——数据并非原子性,因为它是 Firstname和Surname的简单组合。
表二:至少属于1NF,它有一个主码。数据是原子性的。每一个域都有唯一的名字。没有重复数据。
表三:不属于1NF,它有主码,数据是原子性,但是color域重复了,并且这些域的名字也是相同的!
表四:属于1NF,符合1NF的所有规则

思考问题判断1NF
  • 它是否有主码
  • 每一个域的名字是否唯一
  • 数据是否原子性
  • 是否有重复或冗余的域

1NF示例 2

假设为一个粉丝俱乐部网站设计数据库。粉丝们访问网站来寻找志同道合的朋友。

存储的实体如下面所示

2.jpg

这表明每一个乐队都拥有许多粉丝,每一个人是唯一一个乐队的粉丝。

BANDFAN
The attributes of band are:band id ,band name , musictypeThe attributes of a fan are: fan id,firstname, surname,email addresse(s)

数据库需要满足第一范式。

第一次尝试

这是数据库设计者第一次设计数据库,他真的不太确定如何进行。他设计了一个FAN表,并且加载以下记录

FanID[主码]FirstnameSurnameBandID*email
1TomSmith23tm@fan.org
2MaryHolden56mh@fan.org , mary@myhome.org

他成功的建立了一个主码,并且也使用了外码来引用乐队。但是这不属于1NF,因为Mary拥有的两个邮箱地址加载在同一个email域。数据不是原子性了。这样存储数据也很难提取邮箱地址。同时email域的数据长度必须足够大以存储许多邮箱地址,这非常低效率且如果超出一定的范围会产生一定的问题。

第二次尝试

他马上意识到这不是一个好主意,所以打算创建两个email域

FanIDFirstnameSurnameBandID*emailemail2
1TomSmith23tm@fan.org
2MaryHolden56mh@fan.orgmary@myhome.org

这也是一个不好的方法——注意:email2在TOM的记录中未被使用到,造成一定的空间浪费,因此不属于1NF(用于避免冗余和浪费)。另一个问题是假如一个粉丝拥有更多的邮箱那该怎么办?增加更多的email域会使空间浪费更严重。

另一个问题是查询提取邮箱地址更加复杂,因为需要检验每一个email域的邮箱地址。

解决方案

在尝试了几种不同的方法之后,他想到了一个不错的方法——创建另一个email实体,同时在表中使用一个外码去链接粉丝和邮箱地址。ER图如下:

3.jpg

ER表示了每一个粉丝能够拥有许多邮箱地址,但是一个邮箱地址只能属于一个粉丝。

现在FAN和EMAIL表如下所示:

FAN

FanID[主码]FirstnameSurnameBandID*
1TomSmith23
2MaryHolden56

EMAIL

EID[主码]FanID*email
11tm@fan.org
22mh@fan.org
32mary@myhome.org

第二范式-2NF

大多数表格通常都有一个单属性的主码。就像这样:

CUSTOMER

ID [主码]FirstnameSurnameTelephoneemail
2TomSmith22323ts@aol.com

但是有时候一个表拥有的主码是由多个属性构成的,即拥有一个复合主码

CONCERT

Venue [主码]Artist [主码]AttendanceProfitStyle
WembleyGirls Aloud5300012334Girl band
NECLeona Lewis4500066433Female soloist

上面表格中使用了venue和artist作为复合主码。

正是在这种情况下,对于第二范式的额外规则就派上用场了。

  • 非关键属性必须依赖主码的每一部分
  • 表必须已经符合第一范式

所以本质上,任何符合1NF并且有一个单一属性的主码的表同时也符合第二范式了。
思考上面的CONCERT表格——它不属于第二范式。注意到Style属性用于描述artist的风格,它和CONCERT在哪儿演出(即venue)没有任何联系!因此它的值并不依赖主码的每一部分,所以不符合第二范式的规则。

这个规则是为了确保没有冗余的数据被存储。

比如,我们添加另一个Girls Aloud的演唱会记录到表格中

Venue [主码]Artist [主码]AttendanceProfitStyle
WembleyGirls Aloud5300012334Girl band
NECLeona Lewis4500066433Female soloist
NECGirls Aloud7609053789Girl band

注意到Girl band值是重复的,因此导致数据库比原来所需的更大。

构建一个2NF数据库

继续看CONCERT表

Venue [主码]Artist [主码]AttendanceProfitStyle
WembleyGirls Aloud5300012334Girl band
NECLeona Lewis4500066433Female soloist
NECGirls Aloud7609053789Girl band

这个表格需要分解,移除不依赖全部主码的非关键属性,保证它只被存储一次。

在这种情况下,STYLE表格拥有一个artist单一主码

CONCERT

Venue [主码]Artist [主码]AttendanceProfit
WembleyGirls Aloud5300012334
NECLeona Lewis4500066433
NECGirls Aloud7609053789

STYLE

Artist [主码]Style
Girls AloudGirl band
Leona LewisFemale soloist

现在,上面这两个表格已经符合2NF的规则了——每一个非关键属性依赖于全部主码。这里没有冗余的数据了。

构建一个2NF数据库 2

当然,可能有多个属性依赖主码的不同部分,考虑下面的表格

CONCERT

Venue [主码]Artist [主码]DateAttendanceProfitCityNo1HitsStyle
WembleyGirls Aloud1/10/095300012334London5Girl band
NECLeona Lewis1/10/094500066433Birmingham2Female soloist
NECGirls Aloud7/11/097609053789Birmingham5Girl band

像前面的Style属性只依赖于Artist一样,现在NO1Hits也只依赖于Artist。这个表格也包括了只依赖于Venue的City。

所以为了使表格符合第二范式,需要创建四个表格

CONCERT

VenueID [主码]Artist [主码]DateAttendanceProfit
00501121/10/095300012334
00601151/10/094500066433
00601127/11/097609053789

STYLE

Style ID [主码]Style
001Girl band
002Solo artist
003Rap

ARTIST

ArtistID [主码]ArtistNo1HitsStyleID
0112Girls Aloud20001
0115Leona Lewis3002

VENUE

Venue ID [主码]VenueCity
005WemblyLondon
006NECBirmingham

总结

第二范式的规则是

  • 非关键属性必须依赖主码的每一部分
  • 表必须已经符合第一范式

第三范式-3NF

对于一个属于3NF的数据库,需要符合一下规则:

  • 它已经是2NF
  • 没有任何非关键属性依赖其他非关键属性

这么做是为了发现冗余数据的其他来源。如果一个属性的值可以简单的通过表格中的其他属性获得,那么它就不需要存储在这张表格中了。把属性加载到另一张表,同时链接到它会使数据库变得更小。

思考下面的表格

CONCERT

Venue[主码]Artist[主码]Date[主码]AttendanceProfitCityCountry
WembleyGirls Aloud1/10/085300012334LondonUK
NECLeona Lewis1/10/084500066433BirminghamUK
Carnegie HallGirls Aloud7/11/087609053789New YorkUSA

注意到county国家能够通过城市获得——如果演唱会在伦敦举办,那么同时也可以得出也在英国举办——不需要查看主码!
所以为了使数据库符合第三范式,那么可以按下面分解该表格

CONCERT

Venue[主码]Artist[主码]Date[主码]AttendanceProfitCity
WembleyGirls Aloud1/10/085300012334London
NECLeona Lewis1/10/084500066433Birmingham
Carnegie HallGirls Aloud7/11/087609053789New York

CITIES

City[主码]Country
LondonUK
BiminghamUK
New YorkUSA

新的表格CITIES拥有一个City主码和county属性。Concert表格拥有City作为外码,因此现在你能够获取某一特定演唱会举办的国家,同时没有冗余数据产生。

3NF示例

提醒,3NF意味着

  • 它已经是一个2NF
  • 没有任何非关键属性依赖其他非关键属性
示例 1

CUSTOMER

CustomerID[主码]FirstnameSurnameCityPostCode
12123HarryEnfieldLondonSW7 2AP
12443LeonaLewisLondonWC2H 7JY
354SarahBrightmanCoventryCV4 7AL

这不完全符合3NF,因为City能够通过Postcode获得。如果你创建一个包含Postcode的表格,则City可以得到。

CustomerID[主码]FirstnameSurnamePostCode*
12123HarryEnfieldSW7 2AP
12443LeonaLewisWC2H 7JY
354SarahBrightmanCV4 7AL

POSTCODES

PostCode[主码]City
SW7 2APLondon
WC2H 7JYLondon
CV4 7ALCoventry
示例 2
VideoID[主码]TitleCertificateDescription
12123Saw IV18Eighteen and over
12443IgorPGParental Guidance
354BambiUUniversal Classification

Certificate(证书)意思的描述,即Description属性可以从Certificate属性获得——它并不需要查看参考主码VideoID。因此可以使用主码和辅助码的方式分解表格。

示例 3

CLIENT

ClientID[主码]CinemaID*CinemaAddress
12123LON231 Leicester Square. London
12443COV234 Bramby St, Coventry
354MAN456 Croydon Rd, Manchester

CINEMAS

CinemaID[主码]CinemaAddress
LON231 Leicester Square. London
COV234 Bramby St, Coventry
MAN456 Croydon Rd, Manchester

在这种情况下,数据库已经接近3NF,但是因为某些原因,CinemaAddress在CLIENT表格中重复了,即使它可以在CINEMAS表格中获得。因此可以简单的移除CLIENT中的CinemaAddress列。

示例 4

ORDER

OrderID[主码]QuantityPriceCost
12123210.0020.00
12443320.0060.00
354430.00120.00

在这种情况下,Cost能够通过Quantity乘以Price获得。这是一个计算域。数据库会比原本所需的大,因为原本任一菜单的消费能够通过一次查询计算出。因此为了完全符合3NF,需要移除Cost列。

规范化优点

  1. 数据库不含冗余数据,大小更小,节省存储成本
  2. 因为更少的数据需要搜索,因此查询效率更快
  3. 因为没有数据重复,可以更好的保持数据一致性和更少的错误
  4. 因为没有数据重复,所以存储多于2次不同数据的拷贝机会更少
  5. 一旦变化,变化能够立即级联任何相关的记录

规范化缺点

  1. 你需要细心地使数据保持原子性。仅仅因为你能够再次分解数据的类型,它并不总是正确的做法。例如,电话号码可能包含下面这些代码0123456789,但是将电话号码分解成两部分是不明智的。
  2. 和仅有一个未规范化的表格相比,你最后得到的是多个表格
  3. 数据库表格越多,越复杂,查询的速度会越慢
  4. 它需要分配更多的关系来表示大量表格之间的交互
  5. 对于更多表格,建立一个搜索会变得更加复杂

总结

规范化的目的是为了避免数据冗余和更好的维护数据库,只需在一处地方更新一个记录即可。

规范化的特性和范式:

未规范化形式(0NF)

  • 数据可能重复
  • 数据可能非原子性
  • 表格可能没有主码
  • 可能存在重复的域,也就是说每一个域的名字不是唯一的

第一范式(1NF)

  • 没有重复的或相似数据的列
  • 每一项都不能再分割
  • 每一行都是唯一的,也就是说数据库有一个主码
  • 每一个域都有一个唯一的名字

第二范式(2NF)

  • 表必须已经符合第一范式
  • 非关键属性必须依赖主码的每一部分

第三范式(3NF)

  • 它已经是2NF
  • 没有任何非关键属性依赖其他非关键属性

原文链接:Database Design
本文链接:数据库设计

转载于:https://www.cnblogs.com/cposture/p/5053853.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值