不使用数据库生成主键

时间:2010-08-26 13:20:22

标签: java database oracle primary-key

我最近遇到的一个问题是“在5个应用服务器的集群环境中生成主键 - [OAS版本10]而不使用数据库”。

通常我们通过DB序列生成PK,或者将值存储在数据库表中,然后使用SP生成新的PK值...但是当前的要求是为我的应用程序生成主键而不使用引用数据库JDK 1.4。

需要专家帮助才能找到更好的方法来解决这个问题。

谢谢,

10 个答案:

答案 0 :(得分:8)

使用UUID作为主键,generate作为客户端。

修改
自从您发表评论后,我觉得我应该扩展为什么这是一个很好的做事方式。

尽管顺序主键在数据库中最常见,但使用随机生成的主键通常是分布式数据库或(特别是)支持“断开连接”用户界面的数据库的最佳选择,即用户不是始终持续连接到数据库。

UUID是随机生成密钥的最佳形式,因为它们保证非常独特;两次生成相同UUID的可能性非常低,几乎完全不可能。 UUID也无处不在;几乎每个平台都支持内置它们的生成,对于那些没有的平台,几乎总是有第三方库来弥补这一缺陷。

使用随机生成的主键的最大好处是,您可以在客户端构建许多复杂的数据关系(使用主键和外键)(例如,当您准备保存时)只需将所有内容转储到单个批量插入中的数据库,无需依赖插入后步骤来获取以后关系插入的密钥。

另外,UUID是16字节而不是标准的4字节int - 是空间的4倍。这几天真的是个问题吗?我会说不,但我知道有些人会反驳。关于UUID,唯一真正的性能问题是索引,特别是聚簇索引。我将徘徊在SQL Server世界中,因为我不会经常针对Oracle进行开发,这是我目前的舒适区域,并且谈论SQL Server默认情况下会在所有字段上创建聚簇索引。表的主键。这在auto-increment int世界中运行得相当好,并为基于键的查找提供了一些良好的性能。然而,任何值得他的盐的DBA都将以不同的方式聚集,但是那些不关注该聚类并且也使用UUID(微软世界中的GUID)的人往往会对插入量很大的数据库造成一些令人讨厌的减速,因为聚集了index必须在每次插入时重新计算,如果它针对UUID进行集群,这可能会将新密钥放在集群序列的中间,则可能需要重新排列 lot 数据以维护集群指数。这可能是也可能不是Oracle世界中的一个问题 - 我只是不知道Oracle PK是否默认为群集,就像它们在SQL Server中一样。

如果这个连续句很难理解,请记住这一点:如果您使用UUID作为主键,不会在该键上集群

答案 1 :(得分:3)

您可能会发现查找UUID生成很有帮助。

在简单的情况下,一台程序在每台机器上运行一个线程,你可以做一些事情,比如

MAC address + time in nanseconds since 1970.

答案 2 :(得分:2)

如果您无法使用数据库 ,则GUID / UUID是唯一可行的方法。但是,如果您偶尔可以使用数据库 ,请尝试HiLo algorithm

答案 3 :(得分:2)

您应该考虑以UUID的形式使用ID。 Java5有一个class来表示它们(并且还必须有一个工厂来生成它们)。使用此工厂类,您可以将代码反向移植到反对的Java 1.4中,以获得所需的标识符。

答案 4 :(得分:2)

查看Hibernate使用的these strategies(链接中的第5.1.5节)。你肯定会发现它很有用。 它解释了几种方法,它的优点和缺点,还说明它们在集群环境中是否安全。

最重要的是,有可用的代码已经为您实现了:)

答案 5 :(得分:0)

如果它适合您的应用程序,您可以使用更大的字符串键和UUID()函数或SHA1(随机数据)。

对于顺序int,我会把它留给另一张海报。

答案 6 :(得分:0)

您可以根据以下三项内容的组合生成密钥

  1. 机器的IP地址或MAC地址
  2. 当前时间
  3. 每个实例上的增量计数器(以确保在一台计算机上不会生成两次相同的密钥,因为由于基础时间精度,两次即时密钥创建中的时间可能相同)

答案 7 :(得分:0)

通过使用Statement Object,您可以调用statement.getGeneratedKeys();检索执行此Statement对象生成的自动生成的密钥的方法。

Java doc

答案 8 :(得分:0)

以下是MongoDB中的完成方式:{​​{3}}

它们包含时间戳。

但您也可以安装Oracle Express并选择序列,您可以批量选择:

SQL>从级别<双重连接中选择mysequence.nextval 20;

NEXTVAL

     1
     2
     3
     4
     5
    ..  
    20

为什么不允许您使用数据库?资金(Oracle快递是免费的)还是单点故障?或者您希望将来支持除Oracle以外的其他数据库吗?

答案 9 :(得分:0)

它在许多基于Spring的应用程序(如 Hybris -
typeCode是表的名称,例如UserAddress等。

private PK generatePkForCode(final String typeCode)
    {
        final TypeInfoMap persistenceInfo = Registry.getCurrentTenant().getPersistenceManager().getPersistenceInfo(typeCode);
        return PK.createCounterPK(persistenceInfo.getItemTypeCode());
    }