首先,我的平台是IBM i。这意味着我不习惯普通/通用术语,所以可能会稍微滥用它们。
我正在构建一个数据库设计,它定义了“任务”(动作模板)和“作业”,它们是任务的实例化。
任务在TASKS表中定义,并具有主键TASK_ID。还有另一个表TASK_PARMS来定义任务所需参数的属性。它有一个TASK_ID和PARM_SEQ的复合主键,用于定义参数的顺序。在TASK_PARMS和TASKS之间的TASK_ID上将有一个外键。然后,这些是一个如何执行任务的模板(有更多属性字段来实际定义某些操作,但它们与此问题无关)。示例表格值如下。
TASKS TASK_PARMS
+---------+-----------+ +---------+----------+------------+
| TASK_ID | ATTRIBUTE | | TASK_ID | PARM SEQ | ATTRIBUTES |
+---------+-----------+ +---------+----------+------------+
| FOO | PGM_A | | FOO | 10 | ALPHA10 |
+---------+-----------+ | FOO | 20 | DEC5,0 |
+---------+----------+------------+
当我想执行任务时,我实例化一个工作。 JOBS表具有JOB_ID的主键,然后需要定义正在遵循的任务模板。所以它有一个TASKS主键TASK_ID的外键。由于工作由(在概念上,是一个副本)单个任务组成,从标准化的角度来看,这似乎是正确的。
有一个JOB_PARMS表,用于保存此特定作业的实际参数值。当然,它具有JOBS表的JOB_ID外键,但它必须与TASK_PARMS中的序列号具有精确的关系。
JOBS JOB_PARMS
+--------+-----------+ +---------+----------+-----------+
| JOB_ID | TASK_ID | | JOB_ID | PARM SEQ | VALUE |
+---------+----------+ +--------+----------+------------+
| 99 | FOO | | 99 | 10 | XY1000AA |
+--------+-----------+ | 99 | 20 | 2048 |
+--------+----------+------------+
这就是我的问题所在。我无法使JOB_PARMS中的序列字段成为TASK_PARMS的外键,因为JOB_PARMS中不存在TASK_ID。
这表明JOB_PARMS中必须存在TASK_ID,以允许外键关系的完整复合键返回TASK_PARMS。但是,由于作业实际上只是一个任务的实例化,JOB_PARMS中的TASK_ID字段永远不会更改为单个JOB_ID值。这似乎打破了正常化。
我觉得我在这里遗漏了一些东西。我可以将TASK_ID粘贴在JOB_PARMS文件中并继续使用它,但我对所有这一切的感觉都想知道我哪里出错了。
答案 0 :(得分:0)
我认为你原版TASK_ID
中JOB_PARAMS
没有任何问题。
然而,如果它看起来太混乱,你可以尝试这个。创建新作业时,每个任务(1,2,3 ..)的TaskSequenceNo
增量。 Job_ID
是可选的 - 如果存在,则unique not null
。
JobParams
有两个FK约束,类似(可能需要调整语法):
alter table JobParams
add constraint fk1_jp foreign key (TaskId, TaskSequenceNo)
references Job(TaskId, TaskSequenceNo)
, add constraint fk2_jp foreign key (TaskId, Param_Seq)
references TaskParams(TaskId, Param_Seq)
;