Stored procedures 存储过程到DDD中的大量数据操作

Stored procedures 存储过程到DDD中的大量数据操作,stored-procedures,domain-driven-design,long-running-processes,Stored Procedures,Domain Driven Design,Long Running Processes,让我们举一个产品分类的例子所有产品都需要分类为蔬菜或非蔬菜。业务逻辑是,如果该产品来自A、B和C公司,则该产品可以分类为蔬菜。如果该产品不是来自这些公司,则该产品不是蔬菜。有数以百万计的产品。这可以在一个只需几行代码的存储过程中完成。如果同步完成,操作可能只需几秒钟 据我所知,DDD违背了将逻辑放入存储过程的想法。逻辑可以作为产品上的一种行为,可以根据谁是源进行自我分类。要做到这一点,需要将所有一百万个产品读入内存,进行处理,然后将其保存回数据库 这里的问题是此操作需要大量内存。如果操作是在像5

让我们举一个产品分类的例子所有产品都需要分类为蔬菜或非蔬菜。业务逻辑是,如果该产品来自A、B和C公司,则该产品可以分类为蔬菜。如果该产品不是来自这些公司,则该产品不是蔬菜。有数以百万计的产品。这可以在一个只需几行代码的存储过程中完成。如果同步完成,操作可能只需几秒钟

据我所知,DDD违背了将逻辑放入存储过程的想法。逻辑可以作为产品上的一种行为,可以根据谁是源进行自我分类。要做到这一点,需要将所有一百万个产品读入内存,进行处理,然后将其保存回数据库

这里的问题是此操作需要大量内存。如果操作是在像50000这样的卡盘中完成的,那么存储库必须首先弄清楚产品需要如何分类,并且应该告诉域长期运行的操作必须分块进行。当然,这种方法将花费更多的时间,对于那些比进程等待的时间比存储过程等待的时间还要长的用户来说,这将是一种糟糕的用户体验

对于长时间运行的流程,DDD的合理方法是什么?是否预期延迟,因此应用程序必须通知用户分类需要时间,并在分类完成时通知用户?并且不应该使用存储过程,而是具有域的逻辑部分

更新

只是为了增加一些清晰度,这种分类过程是经常进行的。应用程序必须支持分类过程,而不是ETL或不能再等待。这就是为什么我试图在使用存储过程和DDD之间找到折衷


还要注意,它不是一个查询,而是一个命令。该命令可以称为ClassifyAllProductsCommand()。运行此命令时,以前没有分类。分类后,系统的其他用户应看到新的分类。例如,产品A被分类为不可用,分类后可以是蔬菜或肉类。

我认为您混淆了DDD。如果您正在寻找
蔬菜
类型
产品
,您将调用一个服务来检索特定
公司的
产品
。无需将所有产品加载到内存中

应用程序或以领域为中心的设计,只意味着围绕业务领域设计应用程序,而不是从数据库表集合向上设计(如以数据为中心的方法)

相反,最终在应用程序中完成的数据关联(联接)更多,而在单片存储过程中完成的数据关联(联接)更少。它将所有业务逻辑移动到应用程序中,而不是持久化设备(数据库)中,这很有意义

此外,如果您拒绝庞大的表连接,那么您也会仔细考虑传统上会导致数据库大量开销的事情,并最终转向更好的设计,如创建单独的报告数据库、消息总线、异步任务等

编辑

这似乎是DDD中的一个常见短语,但“它取决于您的特定领域”

在不知道细节的情况下,我想知道这些分类发生的频率。在创建
产品时可以执行这些操作吗?他们是经常做还是很少做,是有计划的还是不可预测的

如果这些分类很常见,并且必须在所有一百万种产品中进行,那么最好为
产品
创建一个较小的模型,可能只是使用
SmallProduct.Id
SmallProduct.CompanyId
(可能命名得更好)。然后,数据将这个较小的集合缓存在内存中,并对其执行操作

如果检查产品是否为
蔬菜
是常见的,并且只有少数几种可能的分类之一,那么最好在它们自己的表中有
分类
,并有一个链接表将它们链接到
产品
。然后,问题就变成了一次性的数据设置问题


如果您使用的是文档数据库,那么您可以将这些分类存储在
产品
对象本身的集合中。

当您聚合根时,您将解释“分类”,其中包含产品(作为实体)

老实说,这感觉不是一个好的设计决策(我可能错了,取决于需求细节)

如果您将产品视为聚合根(包含供应商、折扣等),该怎么办?。在这种情况下,一次只需加载一个产品

如果分类/供应商有一个复杂的域,则应该考虑有一个独立的有界上下文。 此外,在您的评论中:

只是为了增加一些清晰度,这种分类过程是经常进行的。应用程序必须支持分类过程,而不是ETL或不能再等待。这就是为什么我试图在使用存储过程和DDD之间找到折衷

真的吗?当供应商有更新时,您不能启动事件并让产品服务更新分类?用户将有一个不一致的状态(例如..“未定义”类别),持续几秒/分钟。这不是很糟糕,是吗


但是,如果您谈论的是批处理作业,那么一定要使用存储过程。

分类是一件有趣的事情。它是一件独立的事情。分类永远不应该作为结构实现……但这是另一回事:)

您的分类甚至可能被视为有界上下文,就像报告可能是有界上下文一样