Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two foreign keys, one of them not NULL: How to solve this in SQL?

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.

like image 892
Blackbam Avatar asked Jul 27 '17 11:07

Blackbam


People also ask

Can a table have 2 foreign keys in SQL Server?

A table can have multiple foreign keys based on the requirement.

How do you make a foreign key NOT null in SQL?

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.

Can foreign key be not null?

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.

Can there be two foreign keys?

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.


1 Answers

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.

like image 194
Gordon Linoff Avatar answered Sep 18 '22 13:09

Gordon Linoff