CQRS和主键:guid与否?

时间:2011-08-02 17:31:11

标签: c# performance key guid cqrs

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

service.SubmitCommand(new AddUserCommand() { UserId = key, ... });

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

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

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

非常感谢!

路德

3 个答案:

答案 0 :(得分:7)

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

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

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

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

考虑到上述情况,选择GUIDs vs INTs在我看来是一分钱而且愚蠢。

答案 1 :(得分:6)

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

用几句话总结这两个链接:

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

答案 2 :(得分:4)

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

  1. 当您创建用户时,您知道用户名,因为您已将其作为命令的一部分提交。
  2. 当您登录时,您知道用户名,因为用户将其作为登录命令的一部分提交。
  3. 如果正确索引用户名列,则可能不需要GUID。验证这一点的最佳方法是运行测试 - 插入一百万条用户记录,并查看CreateUser和Login的执行情况。如果您真的看到严重的性能损失您已经验证会对业务产生负面影响并且无法通过缓存解决,添加Guid。

    如果您正在进行DDD,您将需要专注于保持域清洁,以便代码易于理解并反映实际的业务流程。引入人工密钥与此目标相反,但如果您确定它为业务提供实际价值,那么请继续。