当前项目中使用hibernate框架中的uuid.hex方式自动产生主键,
但出现了一些问题。
基本系统是用java写的,但部分辅助还是用的delphi(C/S结构的),
在delphi写的部分包含大量记录生成,对并发基本无要求,
对速度要求很高,这个时候新记录的主键无法自动产生。
最后是所有delphi系统生成记录用的数据表的主键改用
自动增量了。
因为使用的数据库是oracle,采用的是sequence,相对
sqlserver的要灵活很多,要不是改动太大,很可能整个
项目的数据表都会改。
当前项目中使用hibernate框架中的uuid.hex方式自动产生主键,
但出现了一些问题。
基本系统是用java写的,但部分辅助还是用的delphi(C/S结构的),
在delphi写的部分包含大量记录生成,对并发基本无要求,
对速度要求很高,这个时候新记录的主键无法自动产生。
最后是所有delphi系统生成记录用的数据表的主键改用
自动增量了。
因为使用的数据库是oracle,采用的是sequence,相对
sqlserver的要灵活很多,要不是改动太大,很可能整个
项目的数据表都会改。
>写得非常好,主键是肯定要的,有了之后会方便很多。
>有一种Object ID的方法,也就是专门使用sequence包产生ID,不知属于你总结这些类别中哪一个?
这种方法很好,在实际的编程当中有很高的灵活性,数据库操作越繁杂这种方法体现的优点越明显,不过要请教一下怎么实现? 比如在DB2中select nextval form seq_1? 这样似乎不行啊!
而且这种方法在一种场合下无法使用:确保主键的连贯性。
Identity列能确保连贯,而且通过Statement.getGeneratedKeys()又能得到新增加的键值,这样也解决了主表-明细表插入的问题,因此选Identity列用作主键可谓是比较广泛的选择。
我个人觉得要用主键的话以上两种方法最可取,不过彼此都有一个互补的缺点:前者无法确保连贯;后者在导数据的时候要额外花点心思。
我现在的开发就遇到一种需要确保主键连贯的场合,无法使用第二种主键,而且也不知道如何使用简单的方法实现第一种方法中提到的Object ID,现在我的苯办法是通过select nextval for seq_1 from temp_table fetch first 1 rows only得到ID的! 希望不要被知道诀窍的人笑掉大牙哦!
> 我是直接用表示数据类型的字符串+System.currentTimeMilli
> ();大家说怎么样?
这种方法不太好,如果有并发的话,容易重复。
> 当前项目中使用hibernate框架中的uuid.hex方式自动产生主?> ,
> 但出现了一些问题。
>
> 基本系统是用java写的,但部分辅助还是用的delphi(C/S结?> 的),
> 在delphi写的部分包含大量记录生成,对并发基本无要求,
> 对速度要求很高,这个时候新记录的主键无法自动产生。
>
> 最后是所有delphi系统生成记录用的数据表的主键改用
> 自动增量了。
>
> 因为使用的数据库是oracle,采用的是sequence,相对
> sqlserver的要灵活很多,要不是改动太大,很可能整个
> 项目的数据表都会改。
hibernate中的uuid.hex如果类似GUID的话(本人不是很了解),以上问题其实并不难解决,可以用两种方法:
1。客户端生成GUID,用Delphi很容易的:
function GetGUID: String;
var
g : TGUID;
begin
Result:='';
if S_OK=CreateGuid(g) then
Result:=GUIDToString(g);
end;
2。Oracle生成,如:
insert into a_tab (id,name) values (sys_guid(), 'tom');
个人建议,最好用自己的ID生成组件,这样可移植和可定制性好,使用Hibernate等ID生成定制性不强。
自己定制ID组件很方便,现成源码可见JPetstore中的Sequence类,一个类即可。
我有一疑问,有一表,如下字段:
ID(GUID)主键, 名称, 所属类别, 其它
我插入一条记录,然后再插入一条名称,所属类别都相同的记录,系统不会出现异常, 而我不想让业务上完全相同的两条记录能够被重复插入,怎么办?
我觉得还是用自制加一比较好,楼主说的子公司上报数据可能出现的主键重复问题,可以用这个方法生成主键:公司名+最大序列号,这样子公司名和总公司名设不同就可以避免这种情况了!
序列
这个问题我也想过很久了,后来还是觉得hibernate的uuid比较好,我也把hibernate的uuid算法揪出来了,可以在没有hibernate的情况下使用:
|
|
而且实测效果非常好,在我个人的电脑上每秒可以生成5000个id
我喜欢用系统程序生成,而不是让数据库自己生成。
起码,当我保存一个Bean到数据库时,直接就可以返回系统生成的主键了,而不用再select一次,保存后返回主键很多地方是需要的,不是吗?
而且,好象这样也更灵活吧,比如我想实现分布式的主键,或者各表的键在整个数据库都唯一等等。
是的,用程序产生序列比较好,在Jpetstore 源码中也是有一个专门sequenceDao产生序列号的。
http://www.jdon.com/jdonframework/app.htm
将hibernate组件独立出来是比较好的。
另外,序列号产生器从严格意义来说要求比较高,防止并发需要严格事务支持,还要设置不同的起点,这样减少序列号争夺,所以,序列号产生器组件最好使用现成第三方的。
自动编号主键
缺点:其实缺点也就是来自其优点,就是因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其他系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的);如果其他系统主键不是数字型那就麻烦更大了,会导致修改主键数据类型了,这也会导致其他相关表的修改,后果同样很严重;就算其他系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个“o”(old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。
--------
这个问题在access 和 MSSQL 存在
但是,至少在MySQL 里不存在,MySQL的自动增量类型,是默认值的形式,所以,你也可以填其他的值
使用数值行搜索比字符型搜索,数据量大时快的多的。
至于序列,还是+1,只是生成方式的问题,各数据库的生成方式有些区别