Bla*_*bam 8 mysql sql database-design innodb mysql-5.5
我有一张桌子time。时间条目(1:n 关系)要么属于project条目,要么属于special_work条目。必须设置项目 id 或 special_work id,两者都不是(exclusive 或)。
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;
Run Code Online (Sandbox Code Playgroud)
我怎么能用SQL写这个?除了触发器还有什么办法吗?
如果您确定这是糟糕的数据库设计 - 有没有更好的方法来建模?不过,我不希望有两个不同的时间表。
我的数据库是 Mysql 5.5 InnoDB。
你的数据模型很好。在大多数数据库中,您还需要添加check约束:
alter table `time` add constraint chk_time_project_special_work
check (project is not null xor special_work is null);
Run Code Online (Sandbox Code Playgroud)
但是,MySQL 不支持检查约束。如果您真的喜欢,您可以使用触发器来实现逻辑。
像这样的互斥引用可能表明您的设计中缺少“超类型”表。考虑创建一个代表所有“工作”的新超类型表——项目和特殊工作。项目和特殊工作表将一对一地引用超类型表,其中包含所有项目/工作标识符的联合。然后,时间表只需要一个引用超类型的不可为空的外键。