CQRS和主键:guid与否?

L-F*_*our 11 c# performance guid key cqrs

对于我的项目,这是一个潜在的大型网站,我选择将命令界面与查询界面分开.因此,提交命令是单向操作,不会返回结果.这意味着客户端必须提供密钥,例如:

service.SubmitCommand(new AddUserCommand() { UserId = key, ... });
Run Code Online (Sandbox Code Playgroud)

显然我不能使用int作为主键,所以Guid是一个合乎逻辑的选择 - 除了我到处读到它对性能的影响,这让我感到害怕:)

但后来我也读到了关于COMB Guids,以及它们如何提供Guid的优势,同时仍然具有良好的性能.我还在这里找到了一个实现:Linq-to-Sql中的顺序GUID?.

所以在我做出这个重要决定之前:有人有这方面的经验吗?

非常感谢!

路德

xel*_*ion 7

首先,我使用顺序GUID作为主键,我没有任何性能问题.

大多数测试都Sequential GUID vs INT as primary key使用批量插入操作,并从空闲数据库中选择数据.但在现实生活中,选择和更新发生在相同的时间.

当您应用CQRS时,您将不会有批量插入,并且打开和关闭事务的负担将比1次写入查询花费更多的时间.由于您已将读取存储分开,因此对具有GUID PK的表的选择操作将比在统一存储中具有INT PK的表上的选择操作快得多.

此外,异步,为您提供消息传递,允许您的应用程序比阻止RPC调用的系统更好地扩展.

考虑到上述情况,选择GUIDs vs INTs对我来说似乎是一分钱一分钱而且是愚蠢的.


Chr*_*cht 6

您没有指定您使用的是哪个数据库引擎,但由于您提到了LINQ to SQL,我猜它是MS SQL Server.
如果是,那么Kimberly Tripp就此提出了一些建议:

用几句话概括这两个链接:

  • 顺序GUID比随机GUID执行得更好,但仍然比数字自动增量键更糟糕
  • 为表选择正确的聚簇索引非常重要,尤其是当您的主键是GUID时


Jos*_*off 5

您可能已经拥有一个像用户名这样的自然键,用于唯一地标识用户,而不是向命令提供 Guid(这对于域来说可能毫无意义)。这个自然键对于用户命令来说更有意义:

  1. 创建用户时,您知道用户名,因为您将其作为命令的一部分提交。
  2. 当您登录时,您知道用户名,因为用户将其作为登录命令的一部分提交。

如果正确索引用户名列,则可能不需要 GUID。验证这一点的最佳方法是运行测试 - 插入一百万条用户记录并查看 CreateUser 和 Login 的执行情况。如果您确实看到严重的性能影响,并且已验证对业务产生不利影响并且无法通过缓存解决,那么请添加 Guid。

如果您正在执行 DDD,您将需要重点关注保持域的整洁,以便代码易于理解并反映实际的业务流程。引入人工密钥与该目标背道而驰,但如果您确定它能为业务提供实际价值,那就继续吧。