我有各种类型的任务。每个任务类型都有一组给定的属性。创建任务并分配属性的值。
数据库设计是:
TaskType(pk_taskType,name)
TaskTypeProperty(pk_taskTypeProperty,fk_taskType,name)
任务(pk_task,fk_taskType,name)
TaskProperty(pk_taskProperty,fk_task,fk_taskTypeProperty,value)
一切正常,但有可能给定一个任务,可以更改TaskType引用而不更改属性。这是无效的,但数据库仍然很满意。
是否有更好的架构来表示此场景并在数据库中强制执行?
示例数据:
如果在任务表中将fk_taskType更改为2,则数据库允许它,但我们知道具有与任务T1关联的属性不正确的属性。
答案 0 :(得分:0)
这不应该有问题,这个想法只是为了确保某种类型的任务只允许与该类型相关联的属性。
| 任务类型TYPE_ID
存在。
任务类型由TYPE_ID
标识。
TaskType {TYPE_ID} PK {TYPE_ID}
| 属性PROP_ID
存在。
属性由PROP_ID
标识。
Property {PROP_ID} PK {PROP_ID}
| 任务类型TYPE_ID
与属性PROP_ID
相关联。
对于每个属性,任务类型可以与多个属性相关联 可能有多个任务类型与该属性相关联。
如果任务类型与属性相关联,则该任务类型必须存在。
如果任务类型与属性相关联,则该属性必须存在。
TaskTypeProperty {TYPE_ID, PROP_ID} PK {TYPE_ID, PROP_ID} FK1 {TYPE_ID} REFERENCES TaskType {TYPE_ID} FK2 {PROP_ID} REFERENCES Property {PROP_ID}
| 任务TASK_ID
属于任务类型TYPE_ID
。
每个任务都是一个任务类型;对于每个任务类型,可能更多 这个任务类型不是一个任务。
如果任务属于任务类型,则该任务类型必须存在。
Task {TASK_ID, TYPE_ID} PK {TASK_ID} AK {TASK_ID, TYPE_ID} -- superkey, redundant here but needed in SQL -- to be referenced by a FK FK1 {TYPE_ID} REFERENCES TaskType {TYPE_ID}
| TASK_ID
类型的任务TYPE_ID
具有属性PROP_ID
。
任务可能有多个属性,对于每个属性,多个任务可以拥有该属性。
如果任务类型的任务具有属性,则该属性与该任务类型相关联。
如果任务具有与任务类型相关联的属性,则该任务属于该任务类型。
TaskProperty {TASK_ID, PROP_ID, TYPE_ID} PK {TASK_ID, PROP_ID} FK1 {TASK_ID, TYPE_ID} REFERENCES Task {TASK_ID, TYPE_ID} FK2 {TYPE_ID, PROP_ID} REFERENCES TaskTypeProperty {TYPE_ID, PROP_ID}
注意:
PK = primary key AK = alternate key (unique) FK = foreign key
答案 1 :(得分:0)
根本不需要TaskProperty表。您有TaskTypeProperty表,其中包含每种类型任务的每个属性的条目。我想那些字段pk_taskTypeProperty和fk_taskType构成了该表的复合PK(虽然我当然希望你不要真正命名列" FK _..."或者" PK _... &#34)
。因此在Tasks表中,应该有一个TaskType和TaskProperty字段,它们形成一个到TaskTypeProperty表的FK。现在不能在TaskTypeProperty表中正确定义任务。
Tasks表不需要直接在TaskType表中使用FK。该引用链将通过TaskTypeProperty FK到TaskType表。这是一个非常精美的设计。外键的目的是实现数据完整性,而不是从UML图中复制一行继承。因此,请参考满足该要求的表格。