Domain driven design 在域驱动设计中,guid作为标识字段是否更好?

Domain driven design 在域驱动设计中,guid作为标识字段是否更好?,domain-driven-design,guid,int,identity-column,Domain Driven Design,Guid,Int,Identity Column,当使用guid作为标识字段而不是自动递增整数时,实现域驱动设计是否更容易?使用guid,您不必跳转到数据库来获取实际值。我推荐使用guid,因为您不必对它是什么感到困惑。而且,我知道这经常被当作一个笑话来讨论,但是我不得不调试系统中发生的一个问题,在这个系统中,它在寻找uint而不是guid。这导致sharepoint中的模板被停用,我们无法重新激活它。花了2天时间才发现根本问题所在。因此,回顾一下使用Guid的情况。我看到Guid相对于递增整数的唯一优势是身份创建的分散性。也就是说,递增的整数

当使用guid作为标识字段而不是自动递增整数时,实现域驱动设计是否更容易?使用guid,您不必跳转到数据库来获取实际值。

我推荐使用guid,因为您不必对它是什么感到困惑。而且,我知道这经常被当作一个笑话来讨论,但是我不得不调试系统中发生的一个问题,在这个系统中,它在寻找uint而不是guid。这导致sharepoint中的模板被停用,我们无法重新激活它。花了2天时间才发现根本问题所在。因此,回顾一下使用Guid的情况。

我看到Guid相对于递增整数的唯一优势是身份创建的分散性。也就是说,递增的整数需要原子递增和读取共享值,而guid可以独立创建,不必担心冲突


至于你的建议,即guid允许在不查阅数据库的情况下取消对实体的引用,我看不出是什么情况,因为你的问题中没有提到其他一些信息。您在这里选择的是键类型,而不是是否使用键。如果您手中有一个键,并且该键通过数据库映射到一个值或实体,则需要查阅数据库以取消对该键的引用。

我使用guid有两个原因:

  • ID不仅在创建它的上下文中是唯一的,因此相同类型的数据的ID可以在不同的位置生成。这对于在地理位置上分布多个安装并相互交换数据的情况很好,或者在断开连接的情况下也很好
  • 它反作用于以逻辑方式对待ID的冲动,而是强制开发人员将该值视为“公正和ID”

然而,我不一定要说这些论点只对域驱动设计有效。

DDD的核心原则之一是持久性忽略。因此,是的,guid是为对象提供唯一标识的最简单方法,而无需依赖持久性存储


NB:如果您关注使用GUID的数据库性能,请考虑使用COMBs(特别是针对SQLServer索引碎片)

,GUID很简单,看起来是最合适的。他们对前端程序员很有吸引力,因为他们不必处理数据库

另一方面,当在不考虑太多数据库问题的情况下查看它们在使用时可能存在的缺点时,我会尽可能地警告它们

问题是:在实体存储到数据库之前,您真的需要知道它的ID吗?真的吗为什么?

如果您最终决定使用guid,并且使用sqlserver作为数据库后端(我对其他RDBMS了解不够,无法给出明智的建议),那么我强烈建议您绝对确保guid不被用作表上的集群键。这无疑会扼杀你的表现

如果您确实使用guid作为主键,请确保使用其他内容,即对数据库破坏较小的其他列作为集群键—INT标识将是我的首选

查看Kimberly Tripp的这些文章,了解为什么GUID绝对不是SQL Server数据库中的群集键是一个好主意-在索引和索引性能问题上,她是终极大师,她可以比我做得更好:


马克:不,绝对不是。GUID是一种实现细节,不应泄漏到域中。您需要一个identity-value对象,我不在乎如何实现它。

我认为这完全是倒退。guid与实现细节相反;PK将是一个实现细节。DDD中多次指出,实体的标识符应该是全局唯一的标识符。数据库中是否将其用作PK是另一回事儿,那最好再想想。身份可以是一个相关的领域概念,它的实现不是我甚至不知道这意味着什么。标识符是领域专家想要的任何东西;它是guid、int还是字符串都无关紧要。它不应该像自动递增的int那样与数据库绑定,因为数据库是一个实现细节。guid只是一个值,而不是一个实现细节。此外,在您的域中,您需要一个实体对象,而不是值对象。在实体对象中,您将拥有OP询问的标识符。实体的标识符及其在数据库中的主键是互斥的概念。PK是一个实现细节;域不应该依赖于持久层,也不应该了解持久层。如果你接受这一点,那么选择答案中的一点就更有意义了。实体标识符可以是域设置的guid,而PK可以是自动递增的int。关于从域中抽象持久性实现,问问自己:如果要将数据库切换到平面文件存储,您仍然可以从平面文件中获取ID吗?如果你的答案是否定的,那么你就可以明白为什么你不应该使用它。通过允许域设置实体的标识符(在本例中为guid),可以为域保留该概念。允许数据库也生成一个PK(在本例中为int),它可以在该PK上建立索引;这也是一个实现细节。我不认为这与“在存储之前知道ID”有关,而是域应该是设置ID的域,因为实体的标识符应该是域关注的问题。主键是