【问题标题】:SQL select in n to m relationshipSQL select in n to m 关系
【发布时间】:2012-10-10 16:26:59
【问题描述】:

AuthorBook 之间存在 n 对 m 关系。

表格作者

ID       Name
1        Follett  
2        Rowling
3        Martin

桌书

ID     Title                       Category 
1        A Dance with Dragons      Fantasy
2        Harry Potter              Fantasy
3        The Key to Rebecca        Thriller
4        World without end         Drama

表 book_author

authorId       bookId
1        3  
2        2
3        1
1        4

系统中有更多的作者和书籍。现在我想选择所有拥有“奇幻”类型的书的作者。

这是我目前想到的:

   select distinct a.id 
   from author a, book b, written w 
   where w.authorId = a.id and w.bookId = b.id and b.category = "Fantasy";

我想知道如何优化这个查询,因为特别是表书真的很大。

【问题讨论】:

  • 你的表有索引吗?在哪些列上?

标签: sql


【解决方案1】:

建议使用显式 JOIN 而不是您当前拥有的隐式(逗号分隔的表列表)连接,因为当您需要引入左连接时,它将提高灵活性。

SELECT
  DISTINCT a.id
FROM
  author a
  JOIN book_author ba ON a.id = ba.authorId
  JOIN books b ON b.id = ba.bookId
WHERE b.category = 'Fantasy'

如果您的book_author 已将FOREIGN KEY 关系定义回authorbooks 表,则将强制执行索引。同样,这些表中相应的id 列应定义为PRIMARY KEY。除此之外,您唯一可以做的潜在优化是在books.category 上创建一个索引。

CREATE TABLE book_author (
  authorId INT NOT NULL, /* or whatever the data type... */
  bookId INT NOT NULL,
  /* define FK constraints in book_author */
  FOREIGN KEY (authorId) REFERENCES author (id),
  FOREIGN KEY (bookId) REFERENCES books (id)
);

【讨论】:

  • 嗨。哇,快速回复:)。谢谢你的回答。我实际上已经像这样定义了 fk,并且引用的值是主键。感谢您的宝贵帮助,将使用显式连接。
  • +1 用于在 books.category 上推荐索引。此外,类别应该是一个单独的表格,以避免在数百行中重复类别的名称。
  • 类别索引存在:)。我高度简化了这个例子,以便能够提出一个可以理解的问题,所以这个类别并没有真正重复那么多次。感谢您的意见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多