两个FK有关系时的数据库设计和规范化

时间:2011-12-06 22:11:19

标签: database oracle database-design

我正在尝试开发一个基于Java Web的应用程序,它可以在不同的路径上处理不同的对象。这些对象和路径将在DB中定义为Work Flow Classes and Work Items。现在我正在处理Calculation Assignment对象,该对象根据其选定的计算级别获取其工作流程路径。

以下是我的工作流表计算:

TPQOT_CALC_ASSIGNMENT "Calculation Assignment - Main Object"
=====================
CONSTRAINT dup_wf_instance UNIQUE (WORKFLOW_INSTANCE_ID) 
---------------------
CALC_NUM (PK)        VARCHAR2(6)  "Calculation Number"
CALC_REV (PK)        VARCHAR2(2)  "Calculation Revision Designator"
CALC_DEPT (PK)       VARCHAR2(3)  "Calculation Originating Department"
CALC_LEVEL_ID (FK)   VARCHAR2(24)  "Calculation Level ID"
WORKFLOW_INSTANCE_ID (FK) VARCHAR2(24)  "Workflow Instance Unique ID"


TPQOT_CALC_LEVEL_WORKFLOW "Calculation Level To Work Flow Class Lookup Table"
=========================
CONSTRAINT dup_calclvlwf UNIQUE (CALC_LEVEL, DEPT_OWNER, WORKFLOW_CLASS_ID)
CONSTRAINT dup_calclvl   UNIQUE (CALC_LEVEL, DEPT_OWNER)
-------------------------
CALC_LEVEL_ID (PK)     VARCHAR2(24) "Calculation Level To Work Flow Type Unique ID (Surrogate)"
CALC_LEVEL             VARCHAR2(3) "Calculation Level"
DEPT_OWNER             VARCHAR2(3) "Department Owner"
WORKFLOW_CLASS_ID (FK) VARCHAR2(24) "Work flow Class Unique ID"


WF_WORKFLOW_INSTANCE "Workflow Instances"
====================
WORKFLOW_INSTANCE_ID (PK)  VARCHAR2(24)  "Work Flow Instance Unique ID"
WORKFLOW_CLASS_ID (FK)     VARCHAR2(24)  "Work Flow Class Unique ID"  
STARTED_BY                 VARCHAR2(9)  "Work Flow Instance Started By Badge"  
LAST_DATE                  DATE         "Last date instance was worked"
STATUS                     VARCHAR2(3)  "Workflow Instance Status"


WF_WORKFLOW_CLASS "Workflow process classes by department Reference Table"
=================
CONSTRAINT dup_workflow UNIQUE (DEPT_OWNER, NAME)
-----------------
WORKFLOW_CLASS_ID (PK)   VARCHAR2(24) "Work flow Class Unique ID (Surrogate)"
DEPT_OWNER               VARCHAR2(3)  "Department Owner"
NAME                     VARCHAR2(64)  "Short Name"
DESCRIPTION              VARCHAR2(256)  "Description"
VERSION                  VARCHAR2(2) "Version Number"

当用户启动新的计算工作流程时,他们从下拉菜单中选择一个计算级别,它会告诉我在单击提交时我应该在WF_WORKFLOW_INSTANCE表中存储哪个WORK_FLOW_CLASS_ID。

在TPQOT_CALC_ASSIGNMENT表中存储了两个外键 - CALC_LEVEL_ID& WORKFLOW_INSTANCE_ID - 两者都与其所尊重的表中的相同WORK_FLOW_CLASS相关。

如果编辑了计算分配数据,并且将Calc Level从Level II Calc更改为Level III Calc(与不同的工作流程类相关),该怎么办?

这是否会成为困扰我的瑕疵?我意识到我可以编写代码来确保如果更新Calc Level,那么请确保正确创建新的工作流实例。

您可能想知道为什么我在工作流实例中没有Calc Level权限。这是因为我可能想要创建另一个不使用Level字段的工作流对象,它可能只有一个路径。例如,求职者的简历。

JOB_APPLICANT 
=====================
APPLICANT_ID (PK)
FIRST_NAME
WORKFLOW_INSTANCE_ID (FK)

==== EDIT ==== 如果我从CALC_LEVEL_ID表中删除TPQOT_CALC_ASSIGNMENT该怎么办? TPQOT_CALC_LEVEL_WORKFLOW表将用于Calc Level Pull down,它为我提供WORKFLOW_CLASS_ID来创建WF_WORKFLOW_INSTANCE?查看计算分配表时,我可以对表进行UNION并获取Calc Level标签。有没有?

2 个答案:

答案 0 :(得分:3)

  

如果编辑了计算分配数据和计算级别,该怎么办?   从II级Calc变为III级Calc(与之相关)   不同的工作流程类?)

如果这是您打算允许的更新,那么您有责任对更新做出适当的反应。您可能需要撤消对基表的权限,并通过可更新视图或存储过程处理所有更新。或者您可能需要编写一个或多个触发器。

如果这是您不应允许的更新,那么您不应该允许它。您只能授予INSERT和DELETE权限并撤消UPDATE权限。可能还有其他方法。

允许更新而不对其作出适当的反应会使数据库处于无效状态。由于这是一个应该适用于所有用户的要求,理想情况下应该在数据库中,而不是应用程序代码中。

答案 1 :(得分:2)

如果您发现撤消更新权限过于严格, 您可以使用简单的触发器强制执行规则,如果在未更改工作流ID的情况下更新计算级别,则会引发错误:

CREATE OR REPLACE TRIGGER trg_chk_class_change
BEFORE UPDATE
ON tpqot_calc_assignment 
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE

BEGIN   
    IF :NEW.calc_level_id <> :old.calc_level_id AND :NEW.workflow_class_id  = :OLD.workflow_class_id  THEN
        raise_application_error(-20001, 'Class change only allowed if workflowid is changed'); 
    END IF;    
END;