【问题标题】:Best Practices: Storing a workflow state of an item in a database? [closed]最佳实践:将项目的工作流状态存储在数据库中? [关闭]
【发布时间】:2010-09-12 02:51:34
【问题描述】:

我有一个关于如何存储复杂工作流状态以在数据库中处理任务的最佳做法的问题。我一直在网上寻找无济于事,所以我想我会问社区他们认为什么是最好的。

这个问题来自我在上一个问题中给出的同一个“BoxItem”示例。这个“BoxItem”在我的系统中被跟踪,因为它执行了各种任务。该任务可能会持续数天并需要人工交互,因此必须保持 BoxItem 的状态。还必须跟踪谁执行了任务(如果适用)以及任务完成的时间。

起初,我通过在“BoxItems”表中为每个需要完成的人工交互任务添加三个字段来解决这个问题:

是任务名称完成

日期任务名称完成

用户任务名称完成

当工作流程很简单时,这很有效……但现在它已经发展成为一个复杂的流程(> 流程中可能有 10 种可能的人工交互……其中大约一半是可选的,可能会或可能不会BoxItem,这导致我开始为那些可选任务添加“DoTaskName”字段),我发现应该是一个简单的表现在有 40 个左右的字段专用完全保留此状态信息。

我发现自己在问是否有更好的方法来做到这一点......但我不知所措。

我的第一个想法是制作一个通用的“BoxItemTasks”表,它定义了可以在给定盒子上完成的任务,但我仍然需要单独保存日期和用户信息,所以它并没有真正帮助。

我的第二个想法是,也许这无关紧要,如果这张表有 40 个或更多用于状态保留的字段,我不应该担心......也许我只是偏执。但感觉要保留很多信息。

无论如何,我不知道第三个选项可能是什么,或者上述两个选项中的一个实际上是否合理。我可以看到这个工作流程在未来可能会变得更加复杂,并且对于每个新任务,我需要添加 3-4 个字段来支持它的跟踪......感觉就像它正在失控。

在这种情况下你会怎么做?

我应该注意,这是对现有系统的维护,它是在没有 ORM 的情况下构建的,所以我不能把它留给 ORM 来处理。

编辑:

Kev,你是在说做这样的事情吗:

BoxItems

(PK) BoxItemID

(其他无关的东西)

BoxItemActions

(PK) BoxItemID

(PK) BoxItemTaskID

已完成

完成日期

用户完成

BoxItemTasks

(PK) 任务类型

说明(如有必要)

嗯......这会起作用......它代表需要改变我目前执行 SQL 查询的方式以查看哪些项目处于什么状态,但从长远来看,这样的事情看起来会更好(不必像序列化想法所代表的那样进行基本的设计更改......虽然如果我有时间,我想按照我的想法去做。)。

所以这就是你提到的 Kin,还是我不在乎它?

编辑:啊,我也看到了你的想法,用“最后一个动作”来确定当前状态......我喜欢它!我认为这可能对我有用......我可能需要稍微改变一下(因为在某些时候任务会同时发生),但这个想法似乎是个好主意!

EDIT FINAL:总而言之,如果将来有其他人用同样的问题来查找这个......听起来如果您的系统将信息预加载到它所在的某个界面中,那么序列化方法将很有用可查询的(即不直接调用数据库本身,就像我正在研究的临时系统那样),但如果你没有那个,附加表的想法似乎应该很好用!谢谢大家的回复!

【问题讨论】:

    标签: database database-design refactoring workflow


    【解决方案1】:

    如果我理解正确,我会添加 BoxItemTasks 表(只是一个枚举表,对吗?),然后添加一个 BoxItemActions 表,其中包含 BoxItems 和 BoxItemTasks 的外键,以了解它是什么类型的任务。如果你想让一个特定的任务只能在一个特定的盒子项目上执行一次,只需将 (Items + Tasks) 列对作为 BoxItemActions 的主键。

    (你比我做的好得多,并且正确解释了我所说的话。你写的正是我所想象的。)

    至于确定当前状态,您可以在 BoxItemActions 上编写一个触发器来更新单个列 BoxItems.LastAction。对于并发操作,您的触发器可能只是有特殊情况来决定哪个操作需要最近。

    【讨论】:

    • 啊!我想我明白你是从哪里来的。我没有空间在此评论框中输入我的回复,但我会编辑原始帖子并为您澄清问题。
    • 哦,对于我的后端,我使用的是 SQL Server 2005。我也喜欢你的“最后状态”想法!这甚至可以解决查询问题。甜的!谢谢!
    • 谢谢! =) 是的,出于某种原因,当你说“BoxItemActions”时,我大脑中漂浮的所有不同的部分都突然到位,一切都变得清晰了。 =)
    【解决方案2】:

    正如上一个答案所建议的,我会将您的桌子分成几份。

    BoxItemActions,包含工作流程需要执行的操作列表,每次创建 BoxItem 时都会创建。在此表中,您可以跟踪每个任务完成的详细日期\时间\用户。

    使用这种类型的应用程序,知道 Box 下一步要去哪里可能会变得非常棘手,因此拥有 Box 剩余步骤的“地图”将非常有帮助。同样,这个表可以疯狂地分组,每框数百行,而且仍然很容易查询。

    它还可以轻松更改“不同路径”。通过工作流程的“路径”主数据表是一种解决方案,在创建每个框时,用户必须选择框将遵循的“路径”。或者您可以进行设置,以便在用户创建框时,他们选择此特定框所需的任务。取决于我们的业务问题。

    【讨论】:

      【解决方案3】:

      序列化和数据库模型的混合怎么样。拥有一个用作主工作流文档的 XML 文档,其中包含每个步骤的节点,其中包含详细说明其名称、流程中的顺序、是否可选的条件等的属性和元素。最重要的是,每个步骤节点都可以有一个唯一的步骤 ID。

      然后在您的数据库中,您有一个简单的两个表结构。 BoxItems 表存储您的基本 BoxItem 数据。然后是一个 BoxItemActions 表,非常类似于您标记为答案的解决方案。

      它本质上类似于作为答案接受的解决方案,但不是使用 BoxItemTasks 表来存储任务的主列表,而是使用 XML 文档来为实际的工作流定义提供更大的灵活性。

      【讨论】:

        【解决方案4】:

        不管怎样,在 BizTalk 中,它们通过将长时间运行的消息模式(工作流等)二进制序列化到数据库来“脱水”它们。​​

        【讨论】:

        • 嗯,很有趣...他们如何确定,比如说,哪些项目在步骤 X 中而不阅读整个表格?他们是否将其保留在服务器或其他东西的内存中并将活动状态存储在那里,然后让事物查询 THAT 而不是数据库?有趣……嗯……
        • 我可能需要进一步研究这个想法。我不知道我是否被分配了创建这种解决方案所需的时间,但这个想法很有吸引力......而且绝对是我以前没有想到的!
        【解决方案5】:

        我想我会将 Workflow 对象序列化为 XML 并使用 ID 列存储在数据库中。报告可能会更困难,但听起来它可能适用于您的情况。

        【讨论】:

        • 唯一的问题是我无法真正查询处于某个给定状态的对象了。我绝对认为这个想法(Danimal 几分钟前也表达了类似的想法)会更好,但我必须构建某种“数据库外部”解决方案来
        • 直接处理现在对数据库执行的查询。不过,我开始认为这样的投资可能值得,所以我可能不得不和我的老板谈谈,看看我是否可以开始做这样的事情。
        猜你喜欢
        • 2014-02-20
        • 2014-05-15
        • 2023-02-06
        • 2022-01-18
        • 2015-03-18
        • 2013-01-24
        • 2013-06-30
        • 2017-09-08
        • 1970-01-01
        相关资源
        最近更新 更多