我如何建模这种关系(避免循环)?

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_idfavorite_typefavorite value,其中favorite_type 可能是一本书或作者。然后,您可以从readerreader_favorite 左连接,然后从reader_favorite 表中左连接到bookauthor

然后你只需要确保如果读者在reader_favorite 表中有一个bookauthor 最喜欢的类型的条目,那么这两个值是一致的,但这已经是一个问题,所以:没有伤害,没有犯规。

【讨论】:

【参考方案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;

【讨论】:

以上是关于我如何建模这种关系(避免循环)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kimball 风格的数据仓库中对这种关系进行维度建模?

如何在 Xcode 4 中建模这种关系?

如何在 MongoDB 中建模关系? [复制]

如何在函数式编程中建模继承关系

如何在关系数据库中进行继承建模?

为啥在为数据库设计关系时应该避免循环?