Reputation: 153261
Let's say I want to store two tables, book
and library
, in a city.
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)
The relationship between the 2 tables is multiple-to-multiple. Sometimes I want to get the libraries that have a specific book and sometimes I want to get the books that a library has. To do that, I should have a link table like the following, right?
CREATE TABLE IF NOT EXISTS book_library (
book_id INT FOREIGN KEY REFERENCES book(id),
library_id INT FOREIGN KEY REFERENCES library(id));
And to get the libraries have book with ISBN of 978-3-16-148410-0
, should I do following?
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"));
And to get the book titles of the library 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"));
I am wondering if this is the correct way and most efficient?
Upvotes: 0
Views: 64
Reputation: 180020
The schema and the queries look correct. (But if you know that a subquery will return exactly one result, you can use =
instead of IN
.)
SQLite always implements joins as nested loop joins, so the performance of queries with joins is usually similar to equivalent queries that use subqueries. You should write queries in the most obvious and maintainable way; optimize them only if you have an actual problem.
In general, creating indexes on columns that are used for lookups is likely to make queries faster (for any kind of query). To check whether indexes are actually used in a specific query, use EXPLAIN QUERY PLAN.
The only way to find out which query is faster is to measure them.
Upvotes: 1
Reputation: 11
Here, primary key is isbn in book and name in library, and search is based on Id which is bit confusing.
if you want ISBN and library name to be unique, you can use UNIQUE Constraint.
however you can try JOIN instead of subquery. choosing one of the method is subjective - i have gone thru this blog post IN vs JOIN by Quassnoi
For this query, join is :
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"
Upvotes: 1