I have a simple one-to-many (1:M) relationship but I need to keep a history for the changes.
For example, a task can have many employees, but each employee can only have one task at a time.
I need to keep a history for the task assignments in order to know the past tasks that were assigned to each employee.
I know that I can convert it to a many-to-many (M:N) relationship and add a “flag” column, but this will not keep the relationship constraint that stipulates that only one task can be assigned.
I'm pretty sure that there is a design pattern or best practice for the case but I can't find it. I'm using Oracle DBMS.
Employee
Columns:
- ID
- Task_ID (FK_Task_ID)
- Employee Name
- Other Employee Data
Task
Columns:
- ID (PK)
- Task Details
This is a direct (1:M) relation. The required is what if I want to keep log for all the tasks assigned for a certain Employee? The trivial solution would be make a many to many relation and adding intermediate table as follows:
Employee_Task
Columns:
- ID
- Employee_ID (FK_Employee_ID)
- Task_ID (FK_Task_ID)
This will remove the constraint that each employee should have only one assigned task at a time.
Best Answer
Unsure there is a design pattern for what you are suggesting. A separate history table would accomplish what you want, but from your question it looks like this is not what you are after.
An alternative in Oracle though, I believe is, that you can make a function based unique indexes which would ensure each Employee has a single active task. This would look something like:
This makes use of Oracle not storing NULL values in B-tree indexes, meaning if a task is set to "N", it is not stored in the index tree and therefore all "N" records are not part of the unique index. If you were to try and assign an employee to a task that was active who also was assigned another active task, you should get a unique index violation.