I have got a table time
. A time entry (1:n relationship) either belongs to a project
entry or to a special_work
entry. Either the project id or the special_work id must be set, neither both (exclusive or).
CREATE TABLE `time` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`project` int(20) NOT NULL,
`special_work` int(20) NOT NULL,
`date` date NOT NULL,
`hours` float NOT NULL,
`time_from` time DEFAULT NULL,
`time_to` time DEFAULT NULL,
`notes` text NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`project`) REFERENCES `project`(`id`)
FOREIGN KEY (`special_work`) REFERENCES `special_work`(`id`)
) DEFAULT CHARSET=utf8;
How can I write this in SQL? Any way except for a trigger?
If you are sure this is bad database design - is there a better way to model this? However I do not want to have two different time tables.
My database ist Mysql 5.5 InnoDB.
A table can have multiple foreign keys based on the requirement.
Populate the column with the correct data from the foreign key table. Alter the column add not null. Add the foreign key constraint. You could add the column with a default, then copy over the correct data, then drop the default constraint.
A foreign key containing null values cannot match the values of a parent key, since a parent key by definition can have no null values. However, a null foreign key value is always valid, regardless of the value of any of its non-null parts.
A table may have multiple foreign keys, and each foreign key can have a different parent table. Each foreign key is enforced independently by the database system. Therefore, cascading relationships between tables can be established using foreign keys.
Your data model is fine. In most databases, you would also add a check
constraint:
alter table `time` add constraint chk_time_project_special_work
check (project is not null xor special_work is null);
However, MySQL does not support check constraints. You can implement the logic using a trigger, if you really like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With