2011-11-03 71 views
0

我正在为Java Web应用程序工作流应用程序的数据库设计来跟踪和检查各种业务产品(文档)。但是我的设计和实现有很多不确定性。
这里是我的表:数据库设计一对多

  • WORK_FLOW_CLASS - 定义工作表类型的产品,即流量:报告,演示,工程计算

  • ROLE_CLASS - 工作流角色,即定义表:发起人,检查员,审批人,经理

  • WORK_ITEM_CLASS - 代表某些纸质表格的工作项目定义表,即:作业表单,计算核对表,报告审核表,Clos EOUT清单等,这些形式要求将被按照一定的顺序多个角色被认为完成之前的工作

  • WORK_ACTION_CLASS - 的工作项行动,即定义:通过检查完整的计算清单(一WORK_ITEM)(一ROLE) ,完整的审查报告(一WORK_ITEM)由经理(一个ROLE),完整的审查报告(一WORK_ITEM)通过审批(一ROLE

  • WORK_FLOW_SEQUENCE - 定义表与一个WORK_FLOW_CLASS的许多WORK_ITEM_CLASS ES,即系入门级1计算顺序是:(1)A (2)计算清单,(3)清理清单。部门XYZ 1级计算顺序为:(1)分配表格,(2)清理清单[XYZ选择不在其Calc工作流程中执行清单]。

第一个问题:如若WORK_ACTION_CLASS有一个FK它涉及到WORK_ITEM_CLASS?

或者我应该使用中间表来提供关系?我认为后者是不必要的,因为我不需要将WORK_ACTION与多个WORK_ITEMS相关联,只有一个。

当用户启动一个新的工作流实例时,我的计划是查询CLASS表以获取所选WORK_FLOW_CLASS的详细信息,并将它们实例化到下表中。

  • WORK_FLOW_INSTANCE - 工作流的实际实例 - 我想就像一个购物车订单

  • WFI_WORK_ITEMS - WORK_ITEMs的工作流程实例行项目 - 我想喜欢的产品的订单

  • WFI_WORK_ITEM_ACTIONS - 工作流实例的工作项目操作

这里就是我需要的^ h elp与第二个问题

是否应该有两个单独的表WFI_WORK_ITEMSWFI_WORK_ITEM_ACTIONS或应该有一个复合表?我需要查询工作流实例中的WORK_ITEMS以及包含WORK_ACTIONS子步骤的WORK_ITEMS。

这里是被质疑的两个表的细节。对不起,我不知道描述我的模式的最佳方式。

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_IDWORK_ITEM_CLASS_ID我的想法是,如果我想知道一个工作流的特定实例的WORK_ITEM_ACTIONS,我可以通过查询表WFI_WORK_ITEM_ACTION得到它而无需加入“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 

回答

4

您应该始终以第三范式(3NF)设计表格。如果您了解和减轻影响,恢复到较少的表单(通常是出于性能原因)是完全可以接受的,但从3NF开始

(略简体)规则要记住的是,表中的每个非键列应取决于:

  • 关键,
  • 整个键,
  • 并没有什么,但关键,
  • “所以帮助我,科德” - 一个小DBA的幽默(我的意思是“小”)。

第一个问题很简单。

一对多关系最好在“多”表中表示为外键。所以你提出的是明智的。它允许您自动限制关系。如果你有一个单独的连接表(用于多对多),你需要求助于“欺骗”来强制执行一对多关系。

至于你的第二个问题,你需要看看上面的“Codd”规则,并自己想一想:每个表中的这些行究竟代表什么?如果工作项目操作与工作项目是不同的对象(它们可能与相关但是,如果它们不代表同一个对象,则它们是不同的),它们应该位于不同的表格中。

另外,看起来你有一对多的关系(一个项目可以有很多动作),所以它们应该在不同的表格中,仅仅是出于这个原因。

至于你对冗余信息的查询:如果他们真的冗余,他们应该被修复。

step_num为例,这究竟代表什么?如果它是工作项目的一个属性,它应该不在工作动作表中。

如果您想知道工作操作表中某一行的步骤编号,可以使用外键连接工作项目表。

如果相反它是工作行为的属性,则应将其从工作项表中删除,因为它没有任何意义。你可能有两个动作,每个动作都有不同的步骤号,那么在这种情况下父项的步骤号是什么?

当然,你可能有两个项目行动不同步数 - 在这种情况下,我会考虑重新命名,使意图明确,像item_step_numaction_step_num东西。

底线是以3NF开头。如果在某些时候你的数据库运行速度太慢,,然后考虑回复到较小的形式。然后,您可以在此询问另一个问题,以了解如何识别和缓解由此产生的问题(例如,两个地方的数据不一致的可能性以及使用触发器来防止这些问题)。

+0

+1,该主题的优秀概述。 – DCookie

+0

+1,这与@DCookie所述的原因相同。 –

+0

@paxdiablo - 谢谢你的出色答案。你所说的一切都很有道理。关于步骤编号的部分是肯定的,我需要工作项目和工作项目操作的步骤编号。我会解决这个问题,重构为3NF并重新发布。 – jeff