记录的ID是自动生成好,还是人工赋值好?大家讨论一下。

来源:互联网 发布:势不可挡网络剧免费的 编辑:程序博客网 时间:2024/04/30 19:32
楼主()2001-02-24 14:19:00 在 MS-SQL Server / 基础类 提问

记录的ID是自动生成好,还是人工赋值好?  
   
  自动生成,在oracle   中如何实现?  
   
  create   table   test(  
   
  Id   int   primay   key  
  )  
   
   
  问题点数:0、回复次数:39Top

1 楼houguojun(Alan)回复于 2001-02-24 14:29:00 得分 0

我认为自动好。Top

2 楼Janes168(Janes)回复于 2001-02-24 14:49:00 得分 0

當然是自動生成好!Top

3 楼yangzi(笨笨)回复于 2001-02-24 15:34:00 得分 0

呵呵,不要那么绝对好不好,比如我的ID要以下面的格式:YYYY+MM+DD+六位的流水号,你也能自动生成吗?Top

4 楼zh_r(求知)回复于 2001-02-24 15:56:00 得分 0

当然是人工好,这样可以利用ID表示实际含义,一举两得。Top

5 楼yaw()回复于 2001-02-24 16:28:00 得分 0

YYYY+MM+DD+六位的流水号  
  这样的东西连一范式都不满足,维护起来也很麻烦,为什么不分成两个字段,  
  给用户看时再拼一下就可以了啊啊,代规则的编码早就应该淘汰了,  
  很多国外银行都不使用了。Top

6 楼yangzi(笨笨)回复于 2001-02-24 17:25:00 得分 0

数据库第一范式是什么内容。我请教一下,看看是不是我大学时数据库老师教错了。  
  分成两个字段好吗?呵呵,不一定吧。举个例子:  
  表A:学号(班级ID+流水号),姓名,性别,班级ID(外键,可选)。  
  表B:课目ID(系编号+流水号),课目名称,学分。  
  表C:ID(随便,可以自增长),学号(外键),课目ID(外键),成绩。  
  表D:班级ID,班级名称。  
  如果,我想查某一个班的学生某一门课的总成绩。我就可以直接从表C的学号中折出班级ID来,统计总成绩,而不用检索表A。  
   
  “代规则的编码早就应该淘汰了”:有问题,至少在国际上,对于中文,它的代码页是CP936,好象也不是纯编码的吧。  
   
  “很多国外银行都不使用了”,好象并不都是这样吧。而且,银行也不等于数据库吧。Top

7 楼yaw()回复于 2001-02-24 18:45:00 得分 0

不用一个字段表示两个内容,一范式。  
  关于你的查询可以连接一下,不过这就是另一个问题(先不讨论)。  
  如果你不用ID方式自动产生是否有这样的情况,  
  学生49,被删除,删除其他记录,新加入的学生从数据库MAX出最大学号48,新学生的学号49,  
  区里曾经取得过原49的记录,现在就会造成区里和学校记录的潜在冲突。  
  另外,学校的统计可能是那么简单,但其他的对象没有这么简单,单单代下去一个班级没有什么优势,还有一点浪费空间(很多人认为不重要、)  
  煤炭行业什么编码,乱七八糙一大堆,让用编码去统计,每次都要substring,  
  其实他们的编码只要在类里边拼一下就可以了。  
  说道银行,国外银行的三级科目制度十分先进,统计起来十分方便,  
  像国内的科目可以无限分,科目叫做分层分段,浪费事件和空间,  
  这些不是程序员可以决定的,有人觉得好我们就做背,反正钱是他们的。  
  Top

8 楼yangzi(笨笨)回复于 2001-02-24 20:19:00 得分 0

呵呵,老兄,我的学号是可以维护的。也就是说只要不冲突,我想让它是几,就可以是几。不一定,我非得取max值吧。Top

9 楼yangzi(笨笨)回复于 2001-02-24 20:38:00 得分 0

相反。  
  如果,由于某种原因,需要将某两个学生的学号交换一下,你将如果处理呢?  
        数据库第一范式原文是“如果关系模式R的每一个关系r的属性值是不可分解的,那么称R为1NF模式”。在某些时候,ID仅仅是一个流水号而已,可以用自增长。但大部分时候,ID本身是有意义的(如学号)。你要硬分解开吗?或者,你还需要再加一个没有什么意义的ID吗?你的说法用第一范式解释太牵强了吧。  
   
   
  “单单代下去一个班级没有什么优势”,呵呵  
  不对吧,如果班级的表数据量很大的话,你的查询速度就会看出区别来。  
  sql   server里,我上面所写的查询大该是这样检索的:先用学号里的“班级ID”过滤出符合条件的记录,然后计算总和就可以了。如果按你的方式建外键的话,对于每一个表中的学生,都要从学生表中判断一下是不是本班的学生。然后才决定是否要计入他的成绩。如果一个大学的数据库,学生数在1000以上,班级在200以上,成绩表的记录数在300000左右,你查一下就知道区别了。Top

10 楼yaw()回复于 2001-02-24 21:49:00 得分 0

用ID和A表连接一下就可以了,连接的  
  你说的班级是这样简单的,  
  可是客户呢,一个客户的类别可能是多种的,规模、所有制、行业,  
  曾经有人用行业编码作为客户号的一部分,在交易记录中存在,  
  说行业统计很简单,但单单的行业编码是不满足统计的。  
  我所说的ID不是学号,只是行标识,学号是另外的域。  
  我倒是用1NF去阻止构造复杂的编码,防止为开发造成潜在的隐患,简化开发中无为的花销。Top

11 楼wxj_lake(蔚蓝的风)回复于 2001-02-24 22:27:00 得分 0

个人基本同意yaw()  
  ID是行标识,自动生成有利于维护。代规则的编码适合人工查询,计算机查询在决大多数情况下这样做只能造成编程和维护的麻烦,应该尽量避免。Top

12 楼gxdq(石老人)回复于 2001-02-24 23:24:00 得分 0

自動生成好!Top

13 楼dqj()回复于 2001-02-25 00:15:00 得分 0

关注Top

14 楼Fxx(风萧萧)回复于 2001-02-25 09:14:00 得分 0

自動生成好!   用ORACLE的序列来生成唯一的id号Top

15 楼myair()回复于 2001-02-25 09:30:00 得分 0

自動生成好!   用ORACLE的序列来生成唯一的id号   ?  
   
  如何用sql   语句写出来?  
  谢谢。Top

16 楼yangzi(笨笨)回复于 2001-02-25 13:14:00 得分 0

是行标识,还是ID?在sql   server里好象没有行标识吧。只有在oracle里才有。Top

17 楼yangzi(笨笨)回复于 2001-02-25 13:27:00 得分 0

“我所说的ID不是学号,只是行标识,学号是另外的域”   ,那么你这儿的ID意义何在?或者说有什么用呢?仅仅是表的主键吗?那你是不是还应该维护“学号”的唯一性?  
   
  呵呵,到此为止吧。  
   
  Top

18 楼nature(缘)回复于 2001-02-25 14:13:00 得分 0

都有一定的必要性,不过,大多数情况下还是自动生成好些.  
  我同意yaw的,不要把所有信息都包括在一个编码里,一面以后产生一些隐患Top

19 楼yangzi(笨笨)回复于 2001-02-25 14:17:00 得分 0

好,我保留意见。Top

20 楼myair()回复于 2001-02-25 15:13:00 得分 0

如何自动生成主键?  
  请用sql   语句写一个例子。Top

21 楼mycode(不写代码)回复于 2001-02-25 21:44:00 得分 0

Oracle建表时能自动生成主键?我没有用过,我一般用序列器来处理;  
  insert   into   table(id)  
  values   sequences.nextval;Top

22 楼haor(一个好人)回复于 2001-02-25 23:07:00 得分 0

人工好Top

23 楼yfd(小虫)回复于 2001-02-25 23:28:00 得分 0

这个没有什么可以争论的,自动生成省事、而手工计算比较麻烦、但是程序员可以精确控制Top

24 楼yangzi(笨笨)回复于 2001-02-26 11:34:00 得分 0

呵呵,总算找见一个同盟者。Top

25 楼china_dg_benny(編程是啥)回复于 2001-02-26 12:00:00 得分 0

我也覺得人工好﹗Top

26 楼july(沉船侧畔)回复于 2001-02-26 12:05:00 得分 0

手工与自动之间,主要看实际的需要,如果没有啥需要,当然是自动方便,但是象学生学号之类的,由于其生成的规则不以程序员的需要确定,甚至在某些情况下,还有汉字存在,当然无法自动,至少我知道初中的学号在江苏是需要含有汉字的!!!Top

27 楼zaign(zaign)回复于 2001-02-26 12:35:00 得分 0

是自动还是手工依需要而定,总的无太大分别。  
  有的数据库支持自动产生序列,方便一些;  
  有的数据库不支持自动产生序列,那么只能手工编程产生,稍微麻烦些。  
  所以要考虑移植其他数据库,好的办法是自己编程来产生记录序列ID。  
  Top

28 楼CrazyP(扬帆)回复于 2001-02-26 13:14:00 得分 0

同意楼上的Top

29 楼small_stone(小石头)回复于 2001-02-26 15:43:00 得分 0

me   认为:这个问题没有什么好争论的,纯粹是习惯而已,爱用什么就用什么呗!me   两者都用!:)  
  作为ID,我认为还是自动生成更好一些,便于维护;但有时也确实需要人工生成一些特定的标识,那就两种都用呗,可以么?呵呵。  
  所以我说:如果你的ID没有意义,仅仅是一串数字,自然是自动生成更好一些;反之,那就在自动生成的基础上,再加一个标识吧!:)  
   
  可以接受么?Top

30 楼apusic(apusic)回复于 2001-02-26 21:56:00 得分 0

我认为机器生成的ID好,可以减少维护。Top

31 楼jackylee(编程小子)回复于 2001-02-27 09:29:00 得分 0

    特殊情况特殊处理,我在银行里面做的汇票数据处理系统,他们的汇票贴现表示为:  
  2000贴001,转贴为:2000转贴001,而再贴现由于可能包行了好多的贴现、转贴现,就表示为2000再贴001,所以说银行里面的好多系统ID号也已经用手工生成了。所以我认为手工生成是一种趋势。Top

32 楼FatBoy(白胖)回复于 2001-02-28 18:09:00 得分 0

多数情况下我喜欢用人工的。Top

33 楼myair()回复于 2001-03-01 09:10:00 得分 0

人工生成的话,你应该在另外的表中记录这个生成的ID,  
  如果很多的用户同时需要这个ID时,你怎么保证他的唯一性?  
   
  对生成的ID,在添加记录时   对生成的ID加锁吗?加锁的话,出现死锁怎么办?Top

34 楼yangzi(笨笨)回复于 2001-03-01 10:28:00 得分 0

不一定吧。  
  我一般是取最大值的。  
  很少采用记录最大ID的方法。  
  添加记录时,数据库本身就会加表级的锁。所以不用担心唯一性。  
  数据库出现死锁,多半是database的逻辑设计有问题。与是否自动生成ID关系不大。Top

35 楼myair()回复于 2001-03-01 12:06:00 得分 0

添加记录时,数据库本身就会加表级的锁。是这样。  
   
  我担心取最大值时,有多个用户同时取,这样他们就得到同样的ID了。  
  这样许多用户同时添加记录时,会有问题。  
   
  Top

36 楼yangzi(笨笨)回复于 2001-03-01 12:32:00 得分 0

我一般是把它们写在存储过程里。用事务管理。Top

37 楼liguangyi()回复于 2001-03-01 14:58:00 得分 0

如果在添加纪录时不需要知道纪录的ID号,或者不需要对它处理,就用自动增长好了,  
  没有自动增长的oracle最好是用序列了。如果需要知道纪录的ID号,或者ID有着特定的格式,  
  最好还是手工生成。一般是在另外一个表里保存这个ID,每次读之前采用事务管理,加锁,先加一,然后再读出来。这样不成了Top

38 楼cby(cby)回复于 2001-03-01 19:52:00 得分 0

自动生成ID不用自已维护:方便(懒惰的人用)  
  自己生成比较安全  
  特别是sybase中的identity字段很容易在数据库不正常关闭是出现跳号,而且相当大的范围值  
  sqlserver就不会跳号了  
  我就不知道oracle是否也用跳号  
  create   table   test(Id   int   identity)       ---sqlserver中可以这样  
  create   table   test(Id   numeric(18)   identity)         --sybase中定义identity需是numeric  
  Top

39 楼yangzi(笨笨)回复于 2001-03-01 20:36:00 得分 0

呵呵,这个贴子,该结了吧。 

原创粉丝点击