最近我遇到了一个问题,需要在“没有使用数据库的5个应用服务器的集群环境中生成主键 - [OAS版本10]”。
通常我们通过DB序列来生成PK,或者将值存储在数据库表中,然后使用SP来生成新的PK值...但是当前的要求是在不引用数据库的情况下使用JDK 1.4为我的应用程序生成主键。
需要专家的帮助,以找到更好的处理方法。
谢谢,
最近我遇到了一个问题,需要在“没有使用数据库的5个应用服务器的集群环境中生成主键 - [OAS版本10]”。
通常我们通过DB序列来生成PK,或者将值存储在数据库表中,然后使用SP来生成新的PK值...但是当前的要求是在不引用数据库的情况下使用JDK 1.4为我的应用程序生成主键。
需要专家的帮助,以找到更好的处理方法。
谢谢,
编辑:
自从您的评论以来,我觉得我应该更详细地解释一下为什么这是一个好的做法。
虽然序列主键是数据库中最常见的,但对于分布式数据库或(特别是)支持“断开连接”用户界面的数据库,使用随机生成的主键通常是最佳选择。即用户不会始终与数据库保持连接的UI。
UUID是最好的随机生成密钥形式,因为它们保证非常独特; 生成相同UUID的可能性非常低,几乎完全不可能。 UUID也是无处不在的; 几乎每个平台都内置了生成它们的支持,对于那些没有的平台,几乎总会有第三方库来弥补空缺。
使用随机生成的主键的最大好处是,您可以在客户端上构建许多复杂的数据关系(具有主键和外键),并且(例如当您准备保存时)只需将所有内容转储到数据库中,而无需依赖于后插入步骤以获取稍后关系插入的密钥。
缺点是UUID是16字节而不是标准的4字节int
- 空间增加了4倍。这在今天真的是个问题吗?我认为不是,但我知道有些人会持不同意见。当涉及到UUID时,唯一真正的性能问题是索引,特别是聚集索引。我将进入SQL Server世界,因为我并不经常针对Oracle进行开发,这是我的当前舒适区域,并且谈论SQL Server将默认创建跨表主键的所有字段上的聚集索引。这在自动增量int世界中运作得相当好,并且为基于密钥的查找提供了良好的性能。然而,任何值得他的盐的DBA都将以不同的方式聚类,但是那些不注意聚类且还使用UUID(Microsoft世界中的GUID)的人倾向于在插入重的数据库上遇到一些难以处理的减速,因为聚集索引必须重新计算每个插入,如果它针对UUID进行聚集,则新密钥可能放置在聚集序列的中间,可能需要重新排列大量数据以维护聚集索引。这在Oracle世界中可能是问题,也可能不是问题 - 我只是不知道Oracle PK是否像SQL Server中那样默认聚类。
如果那个长长的句子太难理解了,那么请记住:如果您将UUID用作主键,请勿对该密钥进行聚类!
您可能会发现查找UUID生成很有帮助。
在简单的情况下,每台机器上运行一个程序的一个线程,您可以执行以下操作:
MAC address + time in nanseconds since 1970.
如果你完全无法使用数据库,GUID/UUID是唯一可靠的方法。但是,如果偶尔可以使用数据库,可以尝试使用HiLo算法。
1
2
3
4
5
..
20
为什么不允许使用数据库?是因为钱的原因(Oracle Express是免费的),还是出于单点故障的担忧?或者您想在未来支持除了Oracle之外的其他数据库?
您可以基于以下三个组合生成密钥:
它已经在许多基于Spring的应用程序中默认提供,例如Hybris-
typeCode
是您表格的名称,例如User
、Address
等。
private PK generatePkForCode(final String typeCode)
{
final TypeInfoMap persistenceInfo = Registry.getCurrentTenant().getPersistenceManager().getPersistenceInfo(typeCode);
return PK.createCounterPK(persistenceInfo.getItemTypeCode());
}