JPA实体中客户端生成ID的最终指南2

本文详细探讨了在JPA实体中客户端生成ID的各种策略,包括UUID和专用ID生成服务器。客户端生成ID是分布式应用程序的必要选择,但也带来挑战,如保证唯一性和性能。UUID作为常见解决方案,提供了全局唯一性但可能导致存储空间增加和性能下降。专用ID生成服务器则提供高性能但需要额外维护。文章还讨论了何时分配ID值,以及如何处理实体的平等性和哈希码问题。
摘要由CSDN通过智能技术生成

 在客户端生成ID并不像看起来那么简单。在JPA和Hibernate中,我们可以使用UUID、自定义策略和专用ID生成服务器。

在客户端而不是数据库中生成ID是分布式应用程序的唯一选择。但是在这样的应用程序中生成唯一的ID是很困难的。正确地生成它们非常重要,因为JPA将使用ID来定义实体状态。最安全的选择是使用UUID和Hibernate的生成器,但是从自定义生成器到专用ID生成服务器有更多的选项。

在前一篇文章我们讨论了JPA实体的服务器生成ID。本文中描述的所有ID生成策略都基于一个基本原则:只有一个点负责生成ID:数据库。这个原则可能会成为一个挑战:我们依赖于一个特定的存储系统,因此切换到另一个存储系统(例如,从PostgreSQL到Cassandra)可能是一个问题。此外,这种方法不适用于分布式应用程序,因为我们可以在多个时区的多个数据中心上部署多个DB实例。

在这种情况下,基于客户端的ID生成(或者说,非基于DB的ID生成)进入了一个阶段。这种策略在ID生成算法和格式方面给了我们更大的灵活性,并允许按其性质进行批处理操作:ID值在存储在DB中之前就已经知道了。在本文中,我们将讨论客户端生成的ID策略的两个基本主题:如何生成唯一的ID值以及何时分配它。

生成算法

当涉及到分布式应用中的ID生成时,我们需要决定使用哪种算法来保证唯一性和声音生成性能。让我们看看这里的一些选择。

随机ID和时间戳-糟糕的想法

对于分散ID生成来说,这是一个简单而天真的实现。让每个应用程序实例使用随机数生成器生成唯一的ID,就这样!为了使它更好,我们可能会考虑使用一个复合结构--让我们在随机数的开头附加时间戳(以毫秒为单位),以使我们的ID可以排序。例如,要创建64位ID,我们可以使用时间戳的前32位和随机数的最后32位。

这种方法的问题在于它不能保证唯一性。我们只能希望生成的ID不会冲突。对于大型分布式数据密集型系统,这种方法是不可接受的.除非我们是赌场,否则我们不能依赖概率法则。

结语

我们不应该为全球唯一的ID生成算法重新发明轮子。这需要花费大量的时间、精力和几个博士学位。一些现有的解决方案可以解决这一问题,并可在我们的应用中使用。

UUID:全球唯一

UUID生成-是一种在分布式应用程序中生成ID的广为人知和广泛使用的方法.标准库在几乎所有编程语言中都支持这种数据类型。我们可以在应用程序代码中生成ID值,这个值将是全局唯一的(通过生成算法的设计)。与“传统”数字ID相比,UUID有一些优点:

  • 唯一性不取决于数据表。我们可以使用UUID类型的主键在表或数据库之间移动数据,不会出现问题。
  • 数据隐藏。让我们假设我们开发了一个Web应用程序,用户在登录时会在浏览器的地址中看到以下片段:userId=100。这意味着可能存在一个ID为99或101的用户。知道这些信息可能会导致安全漏洞。

UUID是不可排序的,但是通常不需要通过代理ID值对数据进行排序;我们应该为此使用一个业务密钥。但是如果我们绝对需要排序,我们可以使用UUID子类型-ULID,它代表“普遍唯一的字典排序标识符”。

在大多数情况下,Java中的随机UUID生成器的性能也是足够的。在我的电脑上(AppleM1max),每次操作大约需要500 ns,这就给了我们大约200万UUID每秒。

UUID:缺点

UUID几乎是ID值的最佳选择,但是有一些事情可能会阻止您使用它。

首先,UUID值比64位长ID占用更多的存储空间.如果我们需要精确的话,是空间的两倍。额外

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值