You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
5.4 KiB

12 months ago
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lab 3: More SQL Commands</title>
<link rel="stylesheet" href="../labGuide.css">
<style>
img {
border: 1px solid black;
}
</style>
</head>
<body>
<div id="page">
<!-- Having a fresh database gives them more practice and reduces complexity, compared to building on the previous.
Plus, I can make the example more natural. -->
<h1>Lab 3: More SQL Commands</h1>
<p>In this lab you get experience using SQL junction tables.</p>
<h2>Setting up</h2>
<p>
Start with <a href="https://sql.js.org/examples/GUI/">this SQL interpreter</a> (clear out the default SQL supplied).
Throughout this exercise, test your SQL commands in the interpreter, but <strong>keep a copy of all of your working commands</strong> in your text document. You can also work with a local copy of SQLite if you prefer.
</p>
<h2>Database design</h2>
<p>
We want a database that implements the following entity-relationship-diagram, where each author has written one or more books, and each book is written by one or more authors:<br><br>
<img src="class diagram1.png" width="250"><br><br>
The trouble is there isn't any clean way to implement this with just two database tables. If each book only had one author, then the <code>Books</code> table could just have <code>AuthorID</code> as a foreign key. But then how would you indicate multiple authors? Instead, we will use a <em>junction table</em> to resolve this difficulty:<br><br>
<img src="class diagram2.png" width="450"><br><br>
Every element of the <code>Authors_Books</code> junction table represents a single author being on a single book. We would represent 4 authors on a single book by having 4 entries in the junction table: each with a different AuthorID but the same BookID. We could determine which books someone has authored by looking at all the BookIDs for that given AuthorID.
</p>
<p>
Create tables for Authors and Books, being sure to declare the primary key of each. Then create the junction table as follows. (By the way, &quot;junction table&quot; is only one of many different terms people use for this pattern.)
</p>
<pre><code>CREATE TABLE Authors_Books(
AuthorID INTEGER NOT NULL,
BookID INTEGER NOT NULL,
PRIMARY KEY (AuthorID, BookID),
FOREIGN KEY(AuthorID) REFERENCES Authors(AuthorID),
FOREIGN KEY(BookID) REFERENCES Books(BookID)
);</code></pre>
<p>
We say <code>NOT NULL</code> because it only makes sense to have an entry in our junction table with both an author and a book; the pair of IDs <em>together</em> is the unique association we care about between authors and books, so we defined the primary key where each <em>pair</em> of IDs is unique. We are still free to have authors and books appear multiple times, as long as a given <code>(AuthorID,BookID)</code> pair only appears once. The <code>FOREIGN KEY</code> constraints ensure that we don't end up in a situation where a book or author gets deleted but there is still a reference to it in the <code>Authors_Books</code> table.
</p>
<h2>Populate it</h2>
<p>
Use insert commands to put in the following data.
</p>
<table>
<caption>Authors</caption>
<tr>
<th>Name</th>
</tr>
<tr>
<td>Tolkien</td>
</tr>
<tr>
<td>Gamma</td>
</tr>
<tr>
<td>Helm</td>
</tr>
<tr>
<td>Johnson</td>
</tr>
<tr>
<td>Vlissides</td>
</tr>
<table>
<table>
<caption>Books</caption>
<tr>
<th>Title</th>
<th>Authors</th>
</tr>
<tr>
<td>The Lord of the Rings</td>
<td>Tolkien</td>
</tr>
<tr>
<td>The Hobbit</td>
<td>Tolkien</td>
</tr>
<tr>
<td>Design Patterns</td>
<td>Gamma, Helm, Johnson, Vlissides</td>
</tr>
<tr>
<td>Refactoring</td>
<td>Gamma</td>
</tr>
<tr>
<td>Fundamentals of Argumentation Theory</td>
<td>Johnson</td>
</tr>
<tr>
<td>Pattern Hatching</td>
<td>Vlissides</td>
</tr>
<table>
<h2>Queries</h2>
<p>
<ul>
<li>Write a <code>SELECT</code> command that shows all author names, together with all books authored by them. Note that you will have to use more than one JOIN clause to pull this off. It should look something like this: <code>SELECT ___ FROM ___ JOIN ___ ON ___ JOIN ___ ON ___;</code></li>
</ul>
<ul>
<li>Add a <code>WHERE</code> clause to your SELECT statement so that the results are restricted to whichever AuthorID you choose. You may need to use the full <code>Authors.AuthorID</code> syntax to make the column name unambiguous.</li>
</ul>
</p>
<hr>
<p>When you are done, show me your work to get credit for it.</p>
<hr>
</div>
<!-- https://en.wikipedia.org/wiki/Associative_entity -->
</body>
</html>