我一直在阅读很多关于DDD的文章,并注意到大多数人在持久化到数据库时都使用GUID作为他们的ID。他们说GUID可以很好地扩展,并且在可伸缩性方面,自动递增ID是一个很大的禁忌。
我现在很困惑是使用GUID
还是auto-increment
。
基本上,域名约为membership system (binary tree). (tracking of register members)
第一个要求是我们应该在系统中有一些唯一标识它们的东西(我们称之为Account No.
)或许是7digit。
然后,另一个Members
可以注册新的Member
。我们称之为推荐。
现在我打算做的是将MemberId
GUID类型作为DomainObject Id,它将作为主键用于连接,外键(在Referral上,referer_id将是GUID { {1}})。 MemberId
将是一个自动增量列,或者它可能会通过MAX()+ 1从存储库中获取。主要它将用于系统和链接中的搜索功能。
DomainObject的ID是否应该对系统用户隐藏,因为它只是一个技术实现?
两者结合可以吗? GUID为数据库中的row_id(代理键)。和(自然键)的自动增量?
可以从构造函数中排除AccountNo
,因为它会自动递增吗?那么强制执行不变量的必要性呢?那么从存储库中获取下一个ID是否可以在构造函数中包含AccountNo
?
我应该坚持使用自动增量ID并忘记GUID,删除AccountNo
并让MemberId
成为DomainObject的ID吗?
注:
我没有建立下一个某种类型的脸书。
我只想练习DDD的战术方面,了解如何在知道PROS和CONS的情况下做出艰难的架构决策。
我只想练习DDD的战略方面,学习如何在了解PROS和CONS及其实施的情况下做出艰难的架构决策。
如果我们将通过会员注册制作3个场景:
它将如何影响决策?
技术堆栈:
答案 0 :(得分:3)
在你的问题中可能有太多问题要给你一个完整的答案,因为ID设计不简单并且有很多方面。我可以推荐Vaughn Vernon的“实施DDD”一书,它有一个专门用于身份设计的章节(第5章“实体” - 唯一身份)。
无论如何,我试着指出你正确的方向,而没有背诵那一章中的所有内容:-)。
您已经就ID设计提出了一些问题,但您还需要提出更多问题。只有这样才能确定GUID,DB生成的或仍然不同的ID是否合适。
这些问题的答案将限制您可以使用的ID生成类型。
关于ID设计有一些规则。强烈建议他们跟随他们,这样你以后就不会用脚射击自己:
以下是如何找到ID设计的示例:
允许在后期创建ID(即通过持久性)意味着在创建实体时确实有一个没有ID的实体。因此,如果您需要早期或即时ID,则不能使用DB生成的ID(除非您接受仅为ID检索而联系DB)。
然后您可以决定用户对ID不感兴趣,因此必须指定ID会很奇怪。这会留下应用程序生成的ID
使用应用程序生成的ID,您需要确保ID是唯一的。这对于单实例应用程序来说是微不足道的,但只要您创建具有多个应用程序实例的负载平衡设置,就可能会出现更多问题。这就是为什么许多人首先使用随机ID(例如GUID)的原因,因此当缩小时它们不会达到死胡同。
如您所见,这个例子做了很多假设。没有对错,但有了上述问题,你应该能够做出明智的决定。
答案 1 :(得分:3)
我只想练习DDD的战术方面,以了解如何在知道PROS和CONS的情况下做出艰难的架构决策。
你错了。你不能通过战术学习策略。策略是实施策略的方法。但是你首先需要一个策略。
无论如何关于你的问题,这很简单:使用Guid。它有两个优点
自然ID也应该像AccountNo一样使用。但是,Guid是出于技术目的。自然键格式将来可能会发生变化,Guid可以轻松支持自然键多种格式。
作为一种做法,最好将您的实体ID作为价值对象(即使它只是Guid)。您也可以在AccountNo
中加入guid,VO不需要只有一个值。例如,在我当前的应用中,我有ProjectId(Guid organization,Guid idValue)
和ProjectAssetId(Guid organization,Guid projectId,Guid idValue)
。
答案 2 :(得分:2)
请允许我捍卫自动增量的想法。 GUID确实更具可扩展性。但是,任何设计师在某些时候都应该提出的一个重要问题是"我需要多大的可扩展性?"
答案很少#34;尽可能多!"在现实世界中,一切都有局限。我们的数据库模拟现实世界。
例如,如果您正在与人(用户,客户,学生等)合作,则64位整数可以多次包含整个地球人口。很多次。我们正在谈论银河帝国的人口"这里。使用 bigint ,您可以唯一地识别宇宙中的每个原子。
不要变懒,特别是在设计阶段。设计合理的安全边际并继续。任何更不必要的事情都会增加复杂性和摩擦力。系统。
我在这个领域的经验现在已经过几十年了 - 其中有几个。在那段时间里,我从未使用过GUID来实现可伸缩性。我发现的GUID的唯一实际用途是在不同的,通常是远程的数据库中创建实体,然后必须将它们合并到一个中央数据库中。 GUID消除(统计上讲,即)合并期间发生冲突的可能性。
答案 3 :(得分:0)
他们说GUID可以很好地扩展,并且在可伸缩性方面,自动递增ID是一个很大的禁忌。
自动增量整数的主要可伸缩性问题是插入:由于新值在值范围的上限处“聚集”在一起,因此它们倾向于击中B树的相同“侧”(并且可能是相同的叶节点),导致锁存并降低并发性。
仅插入一分钟,您根本看不到任何此类内容,因此请根据其他条件选择您的密钥。就你所描述的而言,自动增量整数在你的场景中可以正常运行......它们更轻量级,并且可能比GUID更好。如果32位变量不够宽,只需使用64位。
BTW,查询MAX() + 1
不会生成自动增量整数 - 所有DBMS都有自己版本的高性能“序列生成器”,可以直接使用。
您还可以将生成的值直接返回给客户端,而无需额外的往返(例如Oracle的RETURNING或SQL Server的OUTPUT子句)。不幸的是,ORM并不总能很好地发挥...