论坛首页 Java企业应用论坛

[讨论]业务主键 Vs. 逻辑主键,到底哪个好?

浏览 86068 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-02-21  
在做数据库设计的时候,有时候不得不考虑这样的问题。做设计,那么就必须考虑性能、易开发易维护性,所以有时数据库设计不得不放弃高级的范式。
   dlee兄说的会出现修改的唯一属性不能做主键,但是我们忽略了这样一种情况。即业务主键或者说唯一属性是不能修改的,比如身份证可以随便修改吗?也不是,但是现实的社会就有这样的情况,对于任何一样东西都是会修改的,即使是宪法都有可能要修改。我们不能回避这种可能性,理论上唯一的东西在现实中不会是绝对唯一的。毕竟计算机还是要为人所用。
   当然,我们也不能因为这个原因,就将问题一棒子打死,说干脆都用逻辑主键,如果真是那样的话就很变态了!呵呵。
0 请登录后投票
   发表时间:2004-02-21  
是的,我们一般是可以达到第二范式,达到第三范式有些困难,再高的两个范式我们从来没有达到过。
在分析型应用中,几乎全部都是查询操作,为了最大限度提高查询效率,这种故意反模式化的情况就更多了,数据仓库的表中的冗余字段不是很少而是大量的。
0 请登录后投票
   发表时间:2004-02-29  
昨天听 potian 的讲座,potian 是坚决反对使用业务主键的,他说主键不应该有任何的业务含义。原因是什么?就是凤舞凰扬所说的你很难假设哪个业务属性是不会变化的。比如你假设身份证号码是不会变化的,所以用身份证号码作为主键标识某个人,这个主键又作为外键保存在几十张表里。系统刚开始运行时似乎一切正常。积累了几十万条记录后,突然有一天你听说身份证号码要升位,客户要求你们必须平滑地过渡到新的身份证号码上去,想想看你要付出什么样的代价才能做到这件事。
尤其在 ORM 的场合下,几乎全部都是使用逻辑主键,几乎见不到业务主键的影子。

说大项目很少用逻辑主键,感觉真的是有点大言不惭。客户是好骗的,因为他们不懂技术,但是我们是不是应该更多地想想如何对客户负责呢?
0 请登录后投票
   发表时间:2004-03-05  
在我参与的几个项目中都有类似情况,即原使用的很好的业务主键,但因为国家公布了新的标准,导致全部的历史数据都需要重整。所以我更倾向于一般使用逻辑主键,特别是类型这种业务数据,但部分不太可能变化的内容则使用业务主键
0 请登录后投票
   发表时间:2004-03-09  
tomcat 写道
同意!
在很多较大的项目里面,由于历史的原因(这些行业历经多年变化后的数据结构),数据库中每一个字段都有明确的含义。基本上是没有逻辑主键,也没有外键约束。
为什么这样呢?
很简单,实践中得来的,而且这些应用追求的是速度至上!这种设计模式也的确存在很多的问题,比如:修改某表的主键,会引起连锁反应。


如果是现代的中小型应用的话,还是采用流行的设计模式较好。
BTW:在oracle中,外键的支持是从哪一年才有的?

电力的实时控制系统就是追求速度至上的系统。它存储的是电力网各个节点的实时数据。这样的一个系统,都是建立在服务器内存中的,以商用数据库作为其历史数据存储地。其中的绝大多数业务表都是采用逻辑主键的。而且也有很多外键约束。这样的系统也是经过了N*N年的发展才有今天这种设计的。
正因为速度至上,所以,才选择逻辑主键啊。
0 请登录后投票
   发表时间:2004-03-09  
楼上说到了很重要的一点,但是他忽略了。其实在他说的电力这样的系统中,包括电信/银行等很多系统,其实平时说的数据库都只是一个备份的工具,究竟你的数据库采用什么主健和现在讨论的问题关系不大。
0 请登录后投票
   发表时间:2004-03-09  
我用hibernate的第一天就是potian教我们,他给我们讲的第一课就是他以前做的那个杭州市公安局的非机动车管理系统。前面有一位已经提到过了,已经做了数十万辆自行车的注册信息,突然发现身份证号码要从15位升到18位,然后就!@#$%^&*……

我想这个讨论就可以告一段落了。Martin Fowler在POEAA里面也说,O/R mapping的主键绝对不应该有业务含义。如果谁还感觉业务字段可以用来做主键,不妨试着想想这个字段是不是真的真的永远不会变?至于性能问题,我看不出业务主键比逻辑主键强在哪里。一个是“SELECT * WHERE id = ?”,一个是“SELECT * WHERE identityCard = ?”,这有什么不同呢?
0 请登录后投票
   发表时间:2004-03-09  
是不是很多人都把主键和索引搞混了?
0 请登录后投票
   发表时间:2004-03-09  
ozzzzzz 写道
楼上说到了很重要的一点,但是他忽略了。其实在他说的电力这样的系统中,包括电信/银行等很多系统,其实平时说的数据库都只是一个备份的工具,究竟你的数据库采用什么主健和现在讨论的问题关系不大。


我妄测一下ffeliza的意思,是不是内存中的对象模型和采用逻辑主键的数据库模型更为匹配?的确,如果最终的系统基本上是从Cache中load数据,逻辑主键的弱点只剩下大数据量查询的条件下由于多表级联会引起性能损耗了。而这个弱点还可以用索引和硬件来弥补,在条件比较好的环境中也算不了什么事情。

我是坚持使用逻辑主键的(数据字典是我的系统中目前唯一例外)。

业务字段不可能固定不变,这个道理谁都懂,没有人认为车牌号码永不变化。但由于时间/环境等限制,我们常常会被“性能”所诱惑,做出妥协。我现在觉得真是没有必要,多花了不少力气也提高不了多少性能。
0 请登录后投票
   发表时间:2004-03-10  
楼上你对于我说的可能也不明白。你说的查询基本上都不会用到数据库的功能,而只是对于内存中数据的查询,这个时候你根本就不用考虑什么多表的问题。而当你要对那些数据库中的历史数据进行查询的时候,对于效能的要求就不存在那么高的要求了。而我见过单纯对于数据库进行修改而不动内存数据库的情况,这和数据仓库的情况类似。而使用什么方法使程序的设计成为方便往往是这些部分的主要考虑。
具体说到常用的方法,也就是不使用内存数据库的方法,我认为提高效能还是应该以缓存等方式解决。而实际上我认为使用视图的方式往往比使用主键的方式要好些。我是十分反对使用主键的,因为我看不到必须这样做的原因,它所带来的好处,我完全可以通过别的方式得到。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics