我正在为Java Web应用程序工作流应用程序进行数据库设计,以跟踪和检查各种业务产品(文档)。但是我的设计和实施存在很多不确定因素 这是我的表格:
WORK_FLOW_CLASS
- 产品类型工作流程的定义表,即:报告,演示文稿,工程计算
ROLE_CLASS
- 工作流程角色的定义表,即:发起人,检查员,审批人,经理
WORK_ITEM_CLASS
- 代表某种纸质表格的工作项定义表,即:分配表,计算清单,报告审核表,结账清单等。这些表格需要由多个角色来处理在被视为完成之前的某个订单
WORK_ACTION_CLASS
- 工作项操作的定义,即:Checker的完整计算核对表(WORK_ITEM
)(a ROLE
),完整的审核报告({{1 }})经理(WORK_ITEM
),审批人完成审核报告(ROLE
)(WORK_ITEM
)
ROLE
- 将WORK_FLOW_SEQUENCE
与MANY WORK_FLOW_CLASS
相关联的定义表,即部门ABC级别1计算序列为:(1)分配表格,(2)计算清单,(3)收尾清单。部门XYZ 1级计算顺序为:(1)分配表,(2)结账清单[XYZ选择不在其Calc工作流程中进行检查清单]。
第一个问题: WORK_ACTION_CLASS是否应该使用FK将其与WORK_ITEM_CLASS相关联?
或者我应该使用中级表来提供关系?我认为后者是不必要的,因为我不需要将WORK_ACTION与多个WORK_ITEMS相关联,只需要一个。
当用户启动新的工作流实例时,我的计划是查询CLASS表以获取所选WORK_FLOW_CLASS的详细信息,并将它们实例化为下表。
WORK_ITEM_CLASS
- 工作流程的实际实例 - 我想是购物车订单
WORK_FLOW_INSTANCE
- WORK_ITEM的工作流程实例行项目 - 我想就像订单中的产品
WFI_WORK_ITEMS
- 工作流程实例工作项目操作
以下是第二个问题需要帮助的地方。
是否应该有两个单独的表WFI_WORK_ITEM_ACTIONS
和WFI_WORK_ITEMS
,还是应该有一个复合表?我将只需要查询工作流实例中的WORK_ITEMS以及带有子步骤WORK_ACTIONS的WORK_ITEMS。
这里是质疑的两个表的详细信息。抱歉,我不知道描绘我的架构的最佳方式。
WFI_WORK_ITEM_ACTIONS
我似乎在这两个表中有很多冗余信息。但我读过有时会执行去规范化表。
非常感谢我对我的设计的任何帮助。
修改
冗余数据的意思是两个表都列出WFI_WORK_ITEMS
==============
WFI_WORK_ITEM_ID (PK)
WORKFLOW_INSTANCE_ID (FK)
WORK_ITEM_CLASS_ID (FK)
STEP_NUM
LAST_DATE
STATUS
IS_ACTIVE
WFI_WORK_ITEM_ACTION
====================
WFI_WORK_ITEM_ACTION_ID (PK)
WORKFLOW_INSTANCE_ID (FK)
WFI_WORK_ITEM_ID (FK)
WORK_ITEM_CLASS_ID (FK)
STEP_NUM
WORK_ACTION_CLASS_ID (FK)
ACTION_OWNER
LAST_DATE DATE
STATUS
IS_ACTIVE
和WORKFLOW_INSTANCE_ID
我的想法是,如果我想知道WORKFLOW的特定实例的WORK_ITEM_ACTIONS,我可以通过查询表来获取它{ {1}}没有加入'WFI_WORK_ITEM'表格。也许这是错误的想法。 WORK_ITEM_CLASS_ID
也是如此。通过查询WFI_WORK_ITEM_ACTION
表,我知道了ACTION用于的WORK_ITEM的类型。
这是一个更好的设计吗?
WFI_WORK_ITEM ============== WFI_WORK_ITEM_ID (PK) WORKFLOW_INSTANCE_ID (FK) WORK_ITEM_CLASS_ID (FK) WORK_ITEM_STEP_NUM WORK_ITEM_LAST_DATE WORK_ITEM_STATUS WORK_ITEM_IS_ACTIVE WFI_WORK_ITEM_ACTION ==================== WFI_WORK_ITEM_ACTION_ID (PK)WORKFLOW_INSTANCE_ID (FK)WFI_WORK_ITEM_ID (FK)WORK_ITEM_CLASS_ID (FK)WORK_ACTION_STEP_NUM WORK_ACTION_CLASS_ID (FK) ACTION_OWNER WORK_ACTION_LAST_DATE WORK_ACTION_STATUS WORK_ACTION_IS_ACTIVE
答案 0 :(得分:4)
您应该始终以第三范式(3NF)设计表格。如果您理解并减轻影响,那么恢复较小的形式(通常是出于性能原因)是完全可以接受的,但以3NF开始。
要记住的(略微简化的)规则是表中的每个非键列都应该依赖于:
第一个问题很简单。
一对多关系最好在“many”表中表示为外键。所以你提出的建议是明智的。它允许您自动限制关系。如果你有一个单独的连接表(用于多对多),你需要诉诸“欺骗”来强制执行一对多的关系。
关于你的第二个问题,你需要查看上面的“Codd”规则并自己思考:每个表中的这些行究竟代表什么?如果工作项操作是与工作项不同的对象(它们可能与相关,但是,如果它们不表示相同的对象,则它们是不同的),它们应该位于不同的表中。
此外,看起来你在那里有一对多的关系(一个项目可以有很多动作)所以它们应该仅仅因为这个原因而在不同的表中。
关于冗余信息的查询:如果他们真的 多余,则应修复它们。
以step_num
为例,这究竟代表什么?如果它是工作项目的属性,它根本不应该位于工作 action 表中。
您可以从那里删除它,如果您想知道工作操作表中某行的步骤编号,您将使用外键加入工作项表。
如果它是工作操作的属性,则应将其从工作项表中删除,因为它没有意义。您可能有两个操作,每个操作都有不同的步骤编号,那么在这种情况下父项的步骤编号是多少?
当然,对于项目和操作,您可能有 distinct 步骤编号 - 在这种情况下,我会考虑重命名以使意图明确,例如{ {1}}和item_step_num
。
底线是从3NF开始。如果在某些时候您的数据库运行速度太慢,那么然后会考虑将其恢复为较小的形式。然后,您可以在此处询问另一个问题,了解如何识别和缓解由此产生的问题(例如,两个地方可能存在数据不一致,并使用触发器来防止这种情况)。