在MySQL中...这可能不是我追求的关系中最好的例子,但它本质上是我在我的数据库中尝试做的事情(这完全是从我的完整数据模型中简化的)。 / p>
假设我们有一个名为author的表和一个名为book的表。
现在假设我们有一个名为reader的表格,其中列有喜欢的作者和最喜欢的书籍。每个读者都有一个最喜欢的作家,但他们并不都有一本喜欢的书。如果他们确实有一本喜欢的书,那一定是他们最喜欢的作家写的。
我不能只删除favorite_author_id列,因为favorite_book_id可能为null。是否有可能对这种关系建模并避免循环?
答案 0 :(得分:0)
或许有一个reader_favorite
表格,其中包含reader_id
,favorite_type
和favorite value
,其中favorite_type
可能是一本书或作者。然后,您可以从reader
LEFT JOIN到reader_favorite
,然后从book
表左键加入author
和reader_favorite
。
然后你只能确保如果读者在book
表中有author
和reader_favorite
个喜欢的类型的条目,那么这两个值是一致的,但是这已经是一个问题所以:没有伤害,没有犯规。
答案 1 :(得分:0)
你可以尝试使用单独的表:favorites:object_id,object_type,(或类似的东西),然后你会在reader表中找到喜欢的id的单列。这也可以更具扩展性,但它仍然不是很好。
另一个选项(一般来说)可能是约束(并保留你描述的结构),但我认为这对MySQL有问题
答案 2 :(得分:0)
回答我自己的问题。事实证明,我能够使用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;