高质量数据库建模系列课程<6> PPT & 讲义 - 候选键,主键 和 可选键

浏览: 4070

广告:

欢迎参加我的课程:高质量数据库建模



高质量数据建模基础课程 - 6-1.jpg

高质量数据建模基础课程 - 6-2.jpg

大家好, 上一节课我们介绍了关系以及关系的类型. 这节课我们介绍什么是键。

关于键有很多名词,这里呢我就都讲讲是什么意思,目的是为了大家以后看书或者听课的时候有个感性的认识,更容易理解。

我们看看都有哪些键相关的名词。

候选键,主键,可选键,单键,复合键,代理键,自然键,外键。

高质量数据建模基础课程 - 6-3.jpg

那么我们根据键的特点做了一下分类,首先我们来看看候选键,主键和可选键。

什么是候选键呢?对于一个实体而言,它可能有很多属性,而其中某一个,或者多个属性的组合,能够唯一确定该实体的一个实例。

那么什么是主键和可选键呢?就是在候选键中,选中一个作为实体的唯一的标识,这个就是主键。而其他没选的那些,就是可选键。

举个例子,最常见的员工信息表,都有会员工编号,此外员工还有唯一的电子邮件地址,这两个都可以作为候选键,而我们通常会把员工编号作为主键,那么员工的电子邮件就是可选键,也有称为备选键的。

高质量数据建模基础课程 - 6-4.jpg

那么通常被选择作为主键的属性都有哪些特点呢?

1. 首先就是唯一性,这个很显然了,主键的最重要特性唯一。

2. 其次,强制不可以为空。也就是说每个实例在主键对应的属性都必须有值。

3. 第三,不可改变。属性一旦确定,就不能再做修改。

4. 第四,最小集合。比如一个属性组有三个属性A、B和C,而这个属性组可以唯一确定该实体的每一个实例。但这个属性组里面有两个属性A和B就可以唯一确定每个实例,那么就应该把A和B设定为主键,而不是ABC。

除此之外,还有哪些需要注意的地方呢?

高质量数据建模基础课程 - 6-5.jpg

首先, 如果你不能真的准确的预测未来, 就不要建Smart Key。更不要在编码里面加特殊的属性用于程序的编写。

 

这样做的好处可能是速度快,编程效率等等,但会有非常多的隐患,这里举两个例子。

首先,我们最熟悉的例子,身份证。身份证的设计有一些问题,比如有效期和身份证号分别在反正两面,这种设计造成复印起来非常不方便而且容易造假。而身份证编码又可以泄漏很多个人隐私等等,这些我们都不提哈,就单独说身份证的编码设计。一代身份证,15位,当时被设计成整型,而二代身份证18位,因为最后一位有可能会出现校验码X,所以字符型,就这一条,不知道害了多少数据库设计工程师。怎么办?系统大修。还有非常机智的用身份证号码里面求年龄的,直接写code里了, 这么一改, 还得逐行查源码改code。全国相关多少系统?!这有多大的浪费啊!

这里我还想到一个身份证编码的隐患?以18位身份证为例,身份证前6位是省市区,7到14位是出生年月日,然后15到16位相当于序列号,17位标识性别,奇数是男的偶数是女的,第18位是校验码。这样,在一个辖区里,身份证在当前的编码规则下,最大容纳的单天单行政辖区的容量是1000人, 对于单性别是500人。而新中国成立以来,每年最多增加人口是接近3000万,目前最大的行政辖区是北京市朝阳区,多少人呢? 大约400万人口,海淀也有370多万, 这样两个区的人口其实就和一个二线城市规模差不多了。全中国人口13亿7千万,我这边全是按照平均数计算的,平均一天朝阳区增加240个人。看起来240人和1000人有点距离,但是北京这种外地人口比例很高的城市,青壮年的比例相对也比较高,说白了,能生孩子的人口比例很大,并且生孩子也不是一年365天平均着来的,五月份生孩子的就比冬天以及酷暑的时候多。而且中国人还有这癖,生孩子挑年份,比如奥运年就比2007年多生10%。所以二胎一放开,保不齐哪下就忽然有一天一个区的生育数量就超了身份证最大限额了。我也好奇,万一真有这么一天,这几个倒霉孩子身份证号码填啥。所以这里面没多少buffer,是不见得能应对特殊情况的。不过这事后来和其他人聊到这个事,发现我多虑了, 北京户口不好弄, 生那么多孩子也不让你都有北京户口。

也别光说中国的不好,美国的设计更烂。美国的ZIP Code,也就是邮政编码只有5位长,而且前两位还是州的基本信息,也就是说主要用后三位来区分城市和Town。结果被各种数据库设计的书引用为最差实践,应为经常出现好几个town share一个邮政编码的情况。还有美国的社保好吗,SSN。因为号码资源不足,造成人去世了以后,其他人还可以重用,也是非常烂的设计,相比之下我们身份证设计还是不错的。

高质量数据建模基础课程 - 6-6.jpg

然后举一个我遇到的真实的例子,当时做的项目,这事有10多年了,我们有个非常重要的分类表, 是分层级的结构,而这个分类表呢,大约三四年都很少变动。我当时的领导不顾所有人的反对,非常脑残的把层级设计到编码里,如图所示,比如第一层就叫00, 00的子节点就是0001,0002,接下来,比如0001的子节点就是000101, 000102,诸如此类。然后整个系统的程序都是按编码做substr做的,好处是速度挺快,求父节点子节点很方便,有个code就啥都求出来了,结果后来分类的层级关系频繁调整,比如我这边的例子,00010201饲料这个条目被挪到大工业下面去了,而我们的Code都是写死的,没办法怎么办?我只能把原来的删了,然后在大工业下建个新的,但历史数据查看就不方便了,而且我这个没列全,其实在饲料这一层下面还有一层。所以后来变更很多,那么这些Code维护起来就非常困,最后没办法基本上就是把整个系统重新写了一遍,因为code实在太难维护了。

 

所以,Smart Key要慎用,对于外接系统很少或者没有外接系统的,是相对容易预测到未来的,深思熟虑以后是可以用的。对于交易单号这种流水性质的,使用smartkey问题不大,对于身份证号这种主数据性质的数据, 要慎重。

而对于数据仓库这种外接系统很多,而你是很难预测到未来的,Smart Key的使用就有很多隐患的,要非常小心。还是那句话哈,不要因噎废食,我在这里提smart key有隐患,不是不让你用,而是让你用的时候注意未来的场景以及存在的风险。

高质量数据建模基础课程 - 6-7.jpg



此外呢,主键的设计还要考虑,不能随着环境的变化而受到影响,其实也是也是要考虑各方各面以为未来的场景。这里给了一个例子,也是一个真实的例子。说有一个集团公司,一共有三家分公司,AAA, BBB和CCC。然后想建一个员工表,于是分析了一下AAA和BBB的员工编码情况,发现AAA和BBB用的是同一套HR的系统,因此呢重复的员工编码,于是就按照这个结构设置员工代码的主键是一个,就是员工编码。结果后来做推广上线的时候呢,发现CCC公司是被总公司收购的公司,HR系统虽然和AAABBB是一个产品,但并没有和AAA以及BBB数据整合在一起的,结果CCC公司的一些员工的编码会和AAABBB公司的员工编码重复,这样就出问题了,原来的设计就需要做大规模的改动。这个就是一个由于环境的变动引起的数据模型结构的变动,如果前期数据分析做的充分一些,这个设计问题是可以避免的。也就是提醒大家,在设计之初,要考虑未来有哪些环境上的变化。

高质量数据建模基础课程 - 6-8.jpg


还有一点也很重要,就是我们在设计主键的时候呢,要注意主键的可管理性。不要因为键值的构造或者维护过程,而产生大量的管理开销。这种最常见的就是Artificial Key,也就是人工输入的键值,因为难免会有输入错误,比如呢身份证第一代,全国有上百万的重复身份证号,也就是不同人而身份证号一样,这个主要就是由于输入错误引起的,而且设置成主键了,也改不了,只能删了重建,如果还有外键关联又会引起连锁反应。另外呢,再比如我刚才的那个行业层级的那个例子,就是说设计的问题带来数据难以管理。这个也是在设计之初需要考虑的,同时也需要相关的应用程序进行配合。


高质量数据建模基础课程 - 6-9.jpg

下一个键的分类呢,就很容易理解,一种叫单键,如果说主键只有一个属性,那么我们称为单键,也叫Simple Key。如果主键是多个属性的组合,我们称为复合键,CompositeKey。

最后给大家贴一张关系图

高质量数据建模基础课程 - 6-11.jpg


好了,今天键的内容就介绍到这里,下一节课我会用一整节的篇幅讲解代理键和自然键。谢谢!

推荐 7
本文由 BAO胖子 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

Smart Key 是什么意思

要回复文章请先登录注册