我如何建模这种关系(避免循环)?
Posted
技术标签:
【中文标题】我如何建模这种关系(避免循环)?【英文标题】:How can I model this relationship (avoiding loops)? 【发布时间】:2014-10-31 14:43:07 【问题描述】:在 mysql 中...这可能不是我所追求的关系的最佳示例,但它本质上是我试图在我的数据库中做的事情(这从我的完整数据模型中非常简化)。
假设我们有一个名为 author 的表和一个名为 book 的表。
'DB.author': author_id, author_name 'DB.book':book_id、book_name、author_id (这是一种识别关系)现在假设我们有一个名为 reader 的表,其中包含最喜欢的作者和最喜欢的书的列。每个读者都有一个最喜欢的作者,但并不是所有人都有最喜欢的书。如果他们有最喜欢的书,那一定是他们最喜欢的作者写的。
'DB.reader': reader_id, reader_name, favorite_author_id, favorite_book_id我不能只删除 favorite_author_id 列,因为 favorite_book_id 可能为空。是否可以对这种关系进行建模并避免循环?
【问题讨论】:
【参考方案1】:也许有一个reader_favorite
表,其中包含reader_id
、favorite_type
和favorite value
,其中favorite_type
可能是一本书或作者。然后,您可以从reader
到reader_favorite
左连接,然后从reader_favorite
表中左连接到book
和author
。
然后你只需要确保如果读者在reader_favorite
表中有一个book
和author
最喜欢的类型的条目,那么这两个值是一致的,但这已经是一个问题,所以:没有伤害,没有犯规。
【讨论】:
【参考方案2】:您可以尝试使用单独的表:收藏夹:object_id、object_type(或类似的东西),然后您将在阅读器表中有一个列用于收藏 id。这也将更具可扩展性,尽管它仍然不是很好。
另一个选项(通常)可能是约束(并保持您描述的结构),但我认为这对 MySQL 来说是个问题
【讨论】:
【参考方案3】:回答我自己的问题。事实证明,我能够使用 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;
【讨论】:
以上是关于我如何建模这种关系(避免循环)?的主要内容,如果未能解决你的问题,请参考以下文章