Full Question:
From a child table linked to a row in its grandparent table by a foreign key (references grandparent primary key), is it possible to use a field from the referenced grandparent row in the child table's composite foreign key?
My current database design is has a main parent table, Projects. Projects has two child tables, JobTitles and Tasks. Tasks then has a child table Subtasks. Subtasks then has a child table Assignments, which is a x-ref table putting employees on Subtasks. The problem I've come up to is assigning JobTitles to Assignments; JobTitles belong to a Project, and as such the Assignments under any given Project should only be able to reference JobTitles that share a Project. I recently asked this question regarding limiting choice of JobTitle to those sharing a project. However, since then I've found a composite foreign key to be a much cleaner solution.
Simple database layout:
- Projects
- JobTitles
- Tasks
- Subtasks
- Assignments
- Subtasks
I've found how to create a composite key here, but for this I would need to use the Project's primary key as part of the composite foreign key.
Tables:
- Projects
- ProjectName (PK)
- ProjectID (Unique Index)
- JobTitles
- JobTitle
- ProjectID (Foreign Key -> Projects.ProjectID) (Composite PK: JobTitle-ProjectID)
- JobTitleID (Unique Index)
- Tasks
- TaskName
- ProjectID (Foreign Key -> Projects.ProjectID) (Composite PK: TaskName-ProjectID)
- TaskID (Unique Index)
- Subtasks
- SubtaskName
- TaskID(Foreign Key -> Tasks.TaskID) (Composite PK: SubtaskName-TaskID)
- SubtaskID (Unique Index)
- Assignments
- EmployeeID (Foreign Key)
- SubTaskID (Foreign Key -> Subtasks.SubtaskID) (Composite PK: EmployeeID-SubtaskID)
- JobTitleID (Foreign Key -> JobTitles.JobTitleID)
- AssignmentID (Unique Index)
In order to assign a JobTitle to an Assignment, I want to set up a composite foreign key using an Assignment's ProjectID (from its parent Task) and its selected JobTitleID. The only problem is that I have no idea how to grab the ProjectID, which is two generations away, for use in a key. It could be possible to pass the ProjectID down through each generation by wrapping it in a composite key within each table, but composite keys aren't something something to throw around willy nilly considering the toll they take on performance (not to mention passing the value down seems a bit sloppy). Is there any way to get to the ProjectID for use in the key without passing it through the other tables?