当前位置: 首页 > 知识库问答 >
问题:

何时以及如何为DDD中的实体分配唯一id?

韶弘壮
2023-03-14

最好的例子是需要持久化的用户实体。我有以下候选项来为用户分配唯一标识符:

    < li >分配后端(NDB、MySQL等)提供的密钥。). < li >通过某些服务(如系统时钟)手工制作唯一标识符。 < li >像emailId这样的属性。

举一个详细视图的简单例子,我们经常有一个用户的详细显示,比如一些/路径/用户/{user_id},如果我们保持emailId作为唯一ID,那么用户有可能在某一天更改其电子邮件ID并破坏它。

哪个是识别同一实体的更好方法?

共有2个答案

元昊苍
2023-03-14

我同意@VoiceOfUnreason,但仅部分同意。我们都知道UUID很难拼写和追踪。所有使用增量和有意义UUID的方法只能解决这些问题的一部分。

正在使用创建方已经可用的一些id创建聚合。尽管可以在不涉及任何外部组件的情况下生成UUID,但这不是唯一的解决方案。使用像推特雪花(已停用)这样的外部身份提供者也是一种选择。

创建非常简单且可靠的标识提供者并不是很复杂,它可以通过给定聚合类型名称来返回递增的长值。

当然,它增加了复杂性,只有当需要生成顺序唯一数值时,它才是合理的。这项服务的弹性变得非常重要,需要仔细解决。但它可以被视为任何其他关键基础设施组件,我们知道每个系统都有相当多的基础设施组件。

符功
2023-03-14

名叫UUID。

UUID,因为它为标识符提供了一个很好的可预测结构,而不会引入任何语义含义(如您的电子邮件ID示例)。想想代理键。

命名为UUID,因为您希望生成的id具有确定性。确定性意味着可复制:您可以将系统移动到测试环境,并回放命令以检查结果。

它还为您提供了一种检测重复工作的额外方法——如果重复使用create user命令,系统中会发生什么情况(例如:用户两次发布相同的web表单)。有多种方法可以在中间层防止这种情况,但是在持久层(也称为记录系统)中覆盖这种情况的一种非常简单的方法是在id上设置唯一性约束。因为第二次运行该命令会产生一个具有相同id的“新”用户实体,所以持久层会反对重复,您可以从那里处理事情。

因此,即使您的所有中间防护层在重复命令之间的间隔期间重启,您也可以获得幂等命令处理。

命名UUID为您提供了这些属性;例如,您可以根据实体类型的标识符和命令的id构建uuid(复制的命令在重新发送时将具有相同的id)。

可以使用用户的瞬态属性(如电子邮件地址)作为命名 uuid 种子的一部分,前提是可以保证该属性永远不会分配给其他人。您确定不会将 vivek@stackoverflow.com 分配给其他用户吗?那么它就不是一个好用的种子。

如果命令重复,后端密钥分配不会检测到冲突-您需要依赖其他一些状态位来检测冲突。

系统时钟不是一个好的选择,因为它使重现相同的 id 变得困难。如果可以在测试环境中重现对本地时钟的更新,则系统时钟的本地副本可以工作。但是,如果时间还不是您的领域模型的一部分,那么您不希望付出一堆额外的努力。

    < Li > https://www . IETF . org/RFC/RFC 4122 . txt(第4.3节) < Li > http://www . RFC-editor . org/errata _ search . PHP?rfc=4122
 类似资料:
  • 问题内容: 问题在标题中。下面我仅描述了我的一些想法和发现。 当我有一个非常简单的域模型(3个表没有任何关系)时,我所有的实体都没有实现Serializable。 但是,当域模型变得更加复杂时,我遇到了RuntimeException,它表示我的一个实体没有实现Serializable。 我使用Hibernate作为JPA实现。 我想知道: 它是特定于供应商的要求/行为吗? 我的可序列化实体会怎样

  • spark如何给一个执行器分配一个分区? 当我使用 1 个驱动程序和 5 个执行器在火花外壳中运行以下行时: 重新分区后,10个分区仍然位于原来的两个节点上(总共5个)。这似乎非常低效,因为5个任务在包含分区的每个节点上重复运行,而不是平均分布在节点上。在同一个rdds上重复多次的迭代任务中,效率低下最为明显。 所以我的问题是,Spark如何决定哪个节点具有哪个分区,有没有办法强制将数据移动到其他

  • 我想用C++创建一个银行应用程序。所以我想在C++中创建一个唯一的ID,并且在创建ID时必须表示日期。最好的解决办法我会很感激的。谢谢

  • 我目前正在将我的数据库层(实体和DAO)从JavaEE迁移到Quakus(或者从wls迁移到OpenShift),并且不能完全理解一些细节: 目前我有目前的结构: 信息类注册时间。爪哇 我的测试类注册了TimeDaoTest,它使用TestDB在内存中执行以下操作: } 我一直潜伏在quarkus.io,读到以下内容: https://quarkus.io/guides/datasource ht

  • 假设我有一个对象,该对象应包含(政府 ID)对象。我正在从乘客获取。创建对服务器的请求并获取数据(json),而不是解析接收的数据并存储在存储库中。 我很困惑,因为我想将< code>Passport存储为实体,并将其放入< code>PassportRepository中,但所有关于密码的信息都包含在json中,而不是我在上面收到的信息。 我想我应该使用作为 VO 并将其放入(聚合)对象中。或者

  • 我有一个表“MyService”,对两列(名称空间和名称)有唯一的约束,Id是主键名称|类型| |-------------------id |长| |命名空间|字符串| |名称|字符串| |值|字符串| 我想编写单元测试以确保用户不能插入具有相同(命名空间和值)的新行。所以我这样编码: 我有两个问题: 据我所知,如果实体不存在,jparepository将插入,如果实体存在,jpareposit