回答我自己的问题。事实证明,我能够使用 MySQL/InnoDB 中的外键约束来完成这项工作。我不认为我可以有一个有时包含空值的复合外键,但它可以按预期工作。
CREATE TABLE `author` (
`author_id` int(11) NOT NULL AUTO_INCREMENT,
`author_name` varchar(20) NOT NULL,
PRIMARY KEY (`author_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
CREATE TABLE `book` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
`book_name` varchar(25) NOT NULL,
`author_id` int(11) NOT NULL,
PRIMARY KEY (`book_id`,`author_id`),
KEY `fk_book_author` (`author_id`),
CONSTRAINT `fk_book_author` FOREIGN KEY (`author_id`) REFERENCES `author` (`author_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
CREATE TABLE `reader` (
`reader_id` int(11) NOT NULL AUTO_INCREMENT,
`reader_name` varchar(20) NOT NULL,
`favorite_author_id` int(11) NOT NULL,
`favorite_book_id` int(11) DEFAULT NULL,
PRIMARY KEY (`reader_id`),
KEY `fk_reader_favorite_book` (`favorite_book_id`,`favorite_author_id`),
KEY `fk_reader_favorite_author` (`favorite_author_id`),
CONSTRAINT `fk_reader_favorite_author` FOREIGN KEY (`favorite_author_id`) REFERENCES `author` (`author_id`),
CONSTRAINT `fk_reader_favorite_book` FOREIGN KEY (`favorite_book_id`, `favorite_author_id`) REFERENCES `book` (`book_id`, `author_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;