用于多对多关系的链接表

时间:2016-11-03 05:29:35

标签: sql sqlite

假设我想在一个城市中存储两个表booklibrary

CREATE TABLE IF NOT EXISTS book (
       isbn  TEXT   PRIMARY KEY,
       book_title       TEXT   NOT NULL,
       id  INT     NOT NULL);

CREATE TABLE IF NOT EXISTS library (
       library_name  TEXT   PRIMARY KEY,
       location       TEXT   NOT NULL,
       id  INT     NOT NULL)

2个表之间的关系是多对多的。有时我想获得具有特定书籍的图书馆,有时我想获得图书馆的书籍。要做到这一点,我应该有一个如下所示的链接表,对吗?

CREATE TABLE IF NOT EXISTS book_library (
       book_id INT FOREIGN KEY REFERENCES book(id),
       library_id INT  FOREIGN KEY REFERENCES library(id));

为了让图书馆拥有ISBN 978-3-16-148410-0的书,我应该这样做吗?

SELECT libary_name FROM library WHERE id in (SELECT library_id FROM book_library WHERE book_id in (SELECT id FROM book WHERE isbn = "978-3-16-148410-0"));

获取图书馆的书名Gorgeous Library

SELECT bool_title FROM book WHERE id in (SELECT book_id FROM book_library WHERE library_id in (SELECT id FROM library WHERE library_name = "Gorgeous Library"));

我想知道这是否正确,效率最高

2 个答案:

答案 0 :(得分:1)

这里,主键是isbn in book和name in library, 并且搜索基于Id,这有点令人困惑。

如果您希望ISBN和库名称是唯一的,则可以使用UNIQUE Con​​straint。

但是你可以尝试JOIN而不是子查询。 选择其中一种方法是主观的 - 我已经通过这篇博文IN vs JOIN by Quassnoi

对于此查询,请加入:

 Select Distinct L.library_name  from Library L
 join Book_library BL ON L.Id= BL.Library_ID
 join Book B on B.Id= BL.Book_Id
 where B.ISBN = "978-3-16-148410-0"

答案 1 :(得分:1)

架构和查询看起来正确。 (但是,如果您知道子查询只返回一个结果,则可以使用=代替IN。)

SQLite始终将连接实现为嵌套循环连接,因此具有连接的查询的性能通常类似于使用子查询的等效查询。 您应该以最明显和可维护的方式编写查询;只有在遇到实际问题时才能优化它们。

通常,在用于查找的列上创建索引可能会使查询更快(对于任何类型的查询)。 要检查索引是否实际用于特定查询,请使用EXPLAIN QUERY PLAN

找出哪个查询更快的唯一方法是测量它们。

相关问题