论坛首页 Java企业应用论坛

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

浏览 86063 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-12-15  
allenofchina 写道
1000多个?你们光是数据库部分的基本文档就要用麻袋了吧...
汗,不知道你们这个到现在有多少个人年了...

是钢铁企业三级系统,包括 生产,设备,财务,人事劳资。
十来个人做了两年,真正上线已经半年多了,不过偶尔也去修改修改。
0 请登录后投票
   发表时间:2006-04-14  
举例说明一下我们在超市管理系统中的做法:
1)基础表:
  a)商品信息表:
  “商品id”,int4,主键;
  “商品条码”,在业务上是唯一的,varchar(14),唯一索引;
  b)员工信息表:
  “员工id”,int2,主键;
  “员工编码”,在业务上是唯一的,varchar(7),唯一索引;
2)销售流水表,由三个字段组成复合主键:
  “销售时间” timestamp
  “收银员id” int2,外键,引用员工信息表
  “商品id” int4,外键,引用商品信息表
  为什么销售流水表的外键引用的是整数型的 id 呢,主要是考虑到性能,若在销售流水表中使用“员工编码”和“商品条码”,在进行分组汇总时的性能约为前者的三分之一(当时测试了,具体数据记得不清楚),占用的磁盘空间也要小得多。销售流水表使用的频率最多,查明细,查汇总,等等。而且这张表占整个数据库的磁盘空间约90%以上。其实很明显数据库对varchar(14)类型的字段进行分组汇总,比对int4类型的字段进行分组汇总要慢。
  如果将“商品信息表”的主键改为“商品条码”,将“商品id”设置为聚集唯一索引,“销售流水表”的“商品id”还是引用“商品信息表”的“商品id”,这样同样可以,性能也没有变化。
  所以根据我目前的经验得出的结论是:(暂时没有银行、电信等大型系统经验)
  1)数据库中基础表的主键采用与业务无关的id还是采用与业务相关的代码、编码等等都无所谓,关键是业务单据流水表要外键引用基础表的“与业务无关的id”,而不是外键引用基础表的“与业务相关的编码”;
  2)Hibernate 映射文件中的 id 要与基础表的“与业务无关的id”对应,但这个id在数据库中不一定就是“主键”,也可以是“唯一索引”(可能是聚集的)。
  3)基础表的“与业务无关的id”的类型和产生机制要根据系统的实际情况来确定,如果不必要用UUID就不用,能用INT就用INT。使用INT时对数据迁移、合并的影响并不大,因为有唯一的业务字段,一般只需要写一段SQL代码就可以解决了。
0 请登录后投票
   发表时间:2006-04-28  
做个几个小项目,都在百万左右吧。全部用的代理主键(我的理解,就是大家讨论的逻辑主键)。

原因有三个:
第一,业务主键有时会变,由原来的唯一变成不唯一,这个前面大家讨论过,不说了;
第二,有过痛苦的经历,给分公司做的系统,再跟总部的系统整合的时候,发现原来的业务主键无效了。
第三,表现层用struts,经常需要在页面间传递主键,业务主键的内容千奇百怪,处理起来很头痛

加一句,个人认为,在真是世界中,对于一个人,身份证号就是代理主键。
0 请登录后投票
   发表时间:2006-04-30  
未成年人虽然没有身份证,但是有身份证号的。报户口的时候户口本上就写了。看来很多人还没有小孩,没经历过给小孩报户口这种事啊。

身份证号是有业务含义的,包含了地区代码,出生年月,性别。理论上,除非发生身份证号升位,身份证号不会改变。但是只要是由用户维护的数据,信息系统就不能假设它不会变。很简单,用户维护的时候会出错。出错了就要改。逻辑主键应该是指没有业务含义,没有业务用途,因此不需要用户维护,甚至不需要给用户看的。因此它也就绝对不会变。这才能真正满足主键“唯一,不变”的要求。

如果是OLAP用的多维数据库的话,因为数据经过整理,倒入OLAP数据库以后,一般是不会再修改了,那么在导入和整理的过程中可以把逻辑主键替换为业务主键,以提高OLAP应用的性能。但现在有很多系统的问题是直接在OLTP数据库上做数据挖掘,数据仓库一类的应用,而没有认识到OLTP和OLAP应用对数据库结构的要求是不一样的。
0 请登录后投票
   发表时间:2006-06-01  
主键的功能是标示记录,和业务应该毫无关系,业务的变动也不应影响主键。以此原则,无论系统大小,都不应用具有业务含义的字段作为主键。
小系统来说,多一个标示字段对小系统的性能影响可以忽略。
至于大系统,我做过的货运系统,表过百张,数据量日过100万,确也全部采用seqence作为主键。数据迁移当然也遇到seqence冲突问题,只是权衡利害取其轻罢了。
0 请登录后投票
   发表时间:2006-06-13  
hasi 写道
我们做的系统都是一千多个数据库表,
都用逻辑主键。
主键的意义是什么为什么需要主键?
主键,只要能够唯一的表示一条记录就可以,主键本身应该不包括别的含义。


我们的做法基本相同
业务主键一般不会是单独的一个字段,那么,在这种主从关系中,是很痛苦的
尤其是我们做的ERP系统,经常会有多层的级联 H-MD-MD这样的结构,如果使用业务主键,简直是不可想象的
所以,基本上都是UUID作为主键

另外,说到查询性能问题,这个我们专门做过测试
在实际的应用场景中,UUID关联查询比多个业务字段关联查询的效率更高
尤其是再考虑到虚模式等因素的时候,更倾向于UUID的逻辑主键
但是不会使用sequence的自增长字段

PS:我们的数据表有600多个...
0 请登录后投票
   发表时间:2006-09-01  
allenofchina 写道


还有公安用那个身份证号码当主键的,这个确实有点问题,未成年人犯罪没有身份证号码怎么办?设计的时候不考虑这一点未免太粗心吧?


很奇快,怎么好多人都这么说,身份证号是一个人办户口的时候就有的,除非是黑户
0 请登录后投票
论坛首页 Java企业应用版

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