主键的选择,应该是业务有意义还是业务无意义,应该是逻辑主键还是业务主键


刚读完一篇文章http://www.cnblogs.com/xhyang110/archive/2009/11/04 /1595943.html?login=1#commentform,博主的观点是主键应该都是无意义的,不要和业务相关。我很疑惑,疑惑为什么说应该无意义呢,这个应该无意义有什么根据呢?

 

首先我google了一下该类问题,发现大多数人都持有这种观点,甚至出现了主键应对用户无意义的原则”,“主键应该业务无意义的原则”等所谓的金科玉律。说到原则,问题就大了,我翻阅《database system concepts》这本权威书籍以求证。里面提到主键的定义是表中唯一的标识,“应该选择从不变化或极少变化的属性”,我想大家对这个观点都没有异议。但是书中没有指明主键应该业务无意义,倒是举了些例子,比如美国社会保障号,企业唯一标识符均应该作为主键,因为他们从不变化或极少变化。我们可以看出,这两个例子中,主键都是选择了业务有意义作为主键

 

接着,我们来看看 “主键应对用户无意义的原则”这个观点是否站得住脚。 赞成这个观点的人会把“中国身份证”作为主键的设计,在升号时带来的麻烦作为反例。但实际上身份证作为主键设计是没有问题的。用身份证作为主键,对其他数据的引用带来了好处,数据完整性得到保证。升号属于几十年才可能有的事情(也许接下来几十年都不会再升号),这属于极少变化的属性。虽然升级时带来了麻烦,可是否不用身份证作为主键的升级就不麻烦了吗?其实无论选择什么属性作为主键,升级的工作量都是相当的。

 

最后,我举一个例子,说明选择业务有意义的属性作为主键的好处。

比如气象信息数据,有两张表:

一张是记录世界所有观测站信息的表StationInfo(简称SI),SI(stationcode(pk),stationname,经度,维度...)。里面的站号是规定好的,基本上不会变化,但有可能会撤销某站号或增加某站号,这里选择了stationcode这个业务有意义的属性作为主键。

另一张是记录所有气象站点观测气象要素的表StationRecord(简SR),SR(id(pk),

stationcode(fk),temp,humidity,wind,time,...)。所有站点插入这张表时,只插入站号和该站的气象要素,其他什么站名,经纬度均不知道。

两表的关系如图一:


 


 

图一

试想,如果按照“主键应对用户无意义的原则”来设计主键,那么表SI中FStationCode就不能作为主键了,需要增加一个自增字段作为主键,这样一来,表SR中使用什么作为外键和表SI相连?


总结:对于设计,没有真正的银弹,有些设计方法适合这样的应用,有些适合其他的应用,像“主键应对用户无意义”这种设计方法是适合部分应用的,但同时却不适合某些应用。所以无论从权威书籍还是实际应用,都告诉我们“主键应对用户无意义的原则”根本算不上一种原则,如果迷信这种原则,对数据库设计会带来弊端。

对于甲方,数据就是命根子,使用业务主键,数据的完整性,关联性清楚明了,上层业务系统怎么改数据都不会乱,但可能工作量大些(相对)。

对于乙方,总是希望工作量越小越好,所以一般选择逻辑主键,也不管你企业的数据存储空间如何,不管你数据今后好不好升级,不管有没有垃圾数据,只要保证在我的维护期内能搞定即可。

但请注意,在数据大批量修改时,使用业务主键 工作量会大些,但约束使你不会出错;使用逻辑主键,貌似工作量小,但必须很小心,万一出错了,可能数据就会大面积错乱,也许无法弥补。

posted @ 2010-01-23 00:50  橄榄细语  阅读(820)  评论(3编辑  收藏  举报