database - 如何避免首先以 DDD 友好的方式检索聚合根以进行优化?

标签 database performance domain-driven-design ddd-repositories

我写了一个应用程序,并尝试尽可能使用 DDD。我遇到了一个我不确定如何解决的问题。大部分系统是通过 Web 前端由用户驱动的,应用程序的请求量非常低并且本质上相当 CRUDy。然而,系统的一部分集成到其他在线系统中,请求量将是巨大的。我们已经从以前的经验中知道,我们必须尽可能地简化这一点。

场景是我们想要添加创建一个实体,如果它不存在,但如果它确实存在则添加到聚合根。

var foo = fooRepo.Get(id);
if (foo != null)
{
    foo.Bars.Add(new Bar("hello"));
    fooRepo.Add(foo);
}
else
{
    var foo = new Foo();
    foo.Bars.Add(new Bar("hello"));
    fooRepo.Add(fooo);
}

如果操作是由用户发起的,我们不介意,因为它的数量很少。但是系统生成的是额外的 DB 行程以确定它是否存在。我们已经确定这是我们的瓶颈。

我如何以 DDD 方式执行上述操作,但避免额外访问数据库。我开始研究 CQRS,因为我认为该模式的一部分是没有存储库以便我可以执行命令。但我看到大多数 CQRS 示例仍然使用 repos,并且在大多数示例中仍然对聚合根执行获取操作,然后对其进行操作,然后将它们保存回来。

显然,存储库在我的场景中不起作用,因为我无法将问题视为内存中的项目集合。 (事实上​​ ,只有大量数据才能缓存所有内容)。对性能最好的做法是直接写入数据库。

在这种情况下有什么可以做的吗?还是我应该编写一个异常(exception)?

最佳答案

您可以将 FooRepository.AddOrUpdate(foo, bar) 方法实现为直接 INSERT INTO ... IF NOT EXISTSMERGE INTO SQL 语句,如果额外的往返确实是一个问题(我不太确定为什么会这样)。

ETL 或批量导入过程很少遵循与基于 UI 的过程相同的规则或经过相同的层。应用层通常是一个单独的层,在某些情况下您甚至可能想绕过领域层。

从事务的角度考虑第二个输入流可能是个好主意(这些系统生成的更改是成批还是以单元形式出现,您想像隔离两个并发的最终用户事务一样隔离它们,等等.?) 并以此为基础创建特定的应用层。

如果事实证明即使这样您也受到聚合设计的限制,您可能想要完全短​​路域层。

关于database - 如何避免首先以 DDD 友好的方式检索聚合根以进行优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166708/

相关文章:

python - 在 Redis 中存储数据然后获取该数据

css - <img/> 与 background-image (css) 在性能上的对比

java - 在域驱动的设计中,为什么要使用“聚合”对象?在设计聚合时将应用哪些关键原则?

c# - 基本聚合问题

php - 在单个表单中插入到 php 中的多个表中

SQL 表数十亿个条目 - 寻找性能建议

database - 维度建模 : need help doing this star for a university

sql-server - 使用键/对表与 XML 字段和 XPath 的 SQL Server 性能

php - 是否有可能提高这种迭代算法的效率?

laravel - 我应该将相关模型保存在存储库中吗?