Database design 模板->实例化模型中外键的规范化问题

Database design 模板->实例化模型中外键的规范化问题,database-design,foreign-keys,Database Design,Foreign Keys,首先,我的平台是IBMi。这意味着我不习惯使用普通/通用术语,因此可能会稍微误用它们 我正在构建一个数据库设计,它定义了“任务”一个动作模板和“作业”,它们是任务的实例化 任务在TASKS表中定义,并具有主键task_ID。还有另一个表task_参数用于定义任务所需参数的属性。它有一个复合主键TASK_ID和PARM_SEQ,用于定义参数序列。任务参数和任务之间的任务ID上将有一个外键。这些是一个如何执行任务的模板。实际上,有更多属性字段来定义一些操作,但它们与此问题无关。下面是示例表值 TA

首先,我的平台是IBMi。这意味着我不习惯使用普通/通用术语,因此可能会稍微误用它们

我正在构建一个数据库设计,它定义了“任务”一个动作模板和“作业”,它们是任务的实例化

任务在TASKS表中定义,并具有主键task_ID。还有另一个表task_参数用于定义任务所需参数的属性。它有一个复合主键TASK_ID和PARM_SEQ,用于定义参数序列。任务参数和任务之间的任务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,然后需要定义遵循哪个任务模板。因此,它有一个任务主键TASK_ID的外键。由于作业在概念上是由单个任务的副本组成的,从规范化的角度来看,这似乎是正确的

有一个JOB_PARMS表,用于保存此特定作业的实际参数值。当然,它有一个JOB_ID到JOBS表的外键,但它也必须与TASK_PARMS中的序列号有精确的关系

 JOBS                      JOB_PARMS
+--------+-----------+    +---------+----------+-----------+
| JOB_ID | TASK_ID   |    | JOB_ID | PARM SEQ | VALUE      |
+---------+----------+    +--------+----------+------------+
|     99 | FOO       |    |     99 |       10 | XY1000AA   |
+--------+-----------+    |     99 |       20 | 2048       |
                          +--------+----------+------------+
这就是我的问题所在。我无法将JOB_PARMS中的sequence字段设置为TASK_PARMS的外键,因为JOB_PARMS中不存在TASK_ID

这表明TASK_ID必须存在于JOB_PARMS中,以允许外键关系的完整复合键返回TASK_PARMS。然而,由于作业实际上只是一个任务的实例化,作业参数中的任务ID字段对于单个作业ID值永远不会更改。这似乎打破了正常化


我觉得我错过了一些东西。我可以将任务ID粘贴到JOB_PARMS文件中并继续执行,但我的感觉是正确的,我想知道我哪里出了问题。

我看不出将任务ID放在JOB_PARMS文件中有任何问题

然而,如果它看起来太混乱,你可以试试这个。TaskSequenceNo为每个任务1、2、3增加增量。。创建新作业时。作业ID是可选的-如果存在,则唯一不为空

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)
;

谢谢我花了一段时间才弄明白,但我现在明白了基本的方法是通过使用TaskSequenceNumber扩展其键来实例化任务,而不是替换它-从而保持与任务的关系不变。我看得越久,看到的就越多。考虑到保持Job_ID唯一的意图,它实际上可能是key in Job的第二部分。然后它就是我之前拥有的,但在密钥中包含任务ID。我想这就是我的正常化意识崩溃的原因-