|
1 | | -sql-queries |
2 | | -=========== |
| 1 | +# A Toy Database |
3 | 2 |
|
4 | | -Some exercises around SQL queries |
| 3 | +Here is a toy database which models an online music store. In this database, we have falling into three categories: information about the company, information about customers and their orders, and information about the products being sold. |
| 4 | + |
| 5 | +You'll be editing the `queries.sql` file, which consists of a series of |
| 6 | +"plain English" sentences. Your job is to translate those sentences into a |
| 7 | +single SQL `SELECT` query. Don't worry if you can't do it — take your best shot! |
| 8 | + |
| 9 | +## Contents |
| 10 | + |
| 11 | +1. [The Plain English Queries](#the-plain-english-queries) |
| 12 | +2. [Configuring SQLite3](#configuring-sqlite3) |
| 13 | +3. [The Database Tables](#the-database-tables) |
| 14 | + 1. [Information About The Products](#information-about-the-products) |
| 15 | + 2. [Information About Customers and Their Orders](#information-about-customers-and-their-orders) |
| 16 | + 3. [Information About The Company](#information-about-the-company) |
| 17 | +4. [One Key Idea](#one-key-idea) |
| 18 | + |
| 19 | +## The Plain English Queries |
| 20 | + |
| 21 | +See queries.sql. Open the database by running this in your terminal: |
| 22 | + |
| 23 | +```bash |
| 24 | +sqlite3 music-store.db |
| 25 | +``` |
| 26 | + |
| 27 | +Once inside, type the following at the SQLite3 prompt |
| 28 | + |
| 29 | +```text |
| 30 | +sqlite> .schema |
| 31 | +``` |
| 32 | + |
| 33 | +to list all the tables in the database. To see the schema for a specific table, |
| 34 | +you can type, e.g., the `invoices` table |
| 35 | + |
| 36 | +```text |
| 37 | +sqlite> .schema invoices |
| 38 | +``` |
| 39 | + |
| 40 | +Don't be afraid to explore the data in the tables to get a better feeling |
| 41 | +for how it's formatted. It's impossible to damage your database as long |
| 42 | +as you're only running `SELECT` queries. For example, what does the data |
| 43 | +in the invoices table look like? Well, let's look at a 5 rows |
| 44 | + |
| 45 | +```sql |
| 46 | +SELECT * FROM invoices LIMIT 5; |
| 47 | +``` |
| 48 | + |
| 49 | +That's what we mean by "explore." |
| 50 | + |
| 51 | +## Configuring SQLite3 |
| 52 | + |
| 53 | +The default settings for SQLite3 can make it hard to read the output of `SELECT` |
| 54 | +queries. To change these settings, run the following three commands once you're inside |
| 55 | +the SQLite3 shell. You should just be able to copy and paste these three lines. |
| 56 | + |
| 57 | +```text |
| 58 | +.header on |
| 59 | +.mode column |
| 60 | +.width 20 |
| 61 | +``` |
| 62 | + |
| 63 | +It should look roughly like this: http://cl.ly/image/24431S2W0I3f |
| 64 | + |
| 65 | +If you want to make these settings permanent, copy and paste the following |
| 66 | +command into your **terminal** (not the sqlite shell). **Note**: this will not |
| 67 | +work on Windows. |
| 68 | + |
| 69 | +```bash |
| 70 | +cat <<EOF > ~/.sqliterc |
| 71 | +.header on |
| 72 | +.mode column |
| 73 | +.width 20 |
| 74 | +EOF |
| 75 | +``` |
| 76 | + |
| 77 | +You should copy and paste all 5 lines and it should look roughly like this: http://cl.ly/image/3w1Y0l1a0W38 |
| 78 | + |
| 79 | +Don't worry about what all the parts of this command are. The short of it is |
| 80 | +that this is adding lines to a file named `.sqliterc`, which SQLite3 uses to |
| 81 | +determine its default settings. |
| 82 | + |
| 83 | +## The Database Tables |
| 84 | + |
| 85 | +Remember: relational databases are organized into tables. Each table has a "schema", which dictates the fields (aka columns) that the data in the table can or must contain. The data itself is stored as records (aka rows). |
| 86 | + |
| 87 | +Here are the tables, organized by high-level purpose. |
| 88 | + |
| 89 | +### Information About The Products |
| 90 | + |
| 91 | +1. `albums` are the albums our store is selling |
| 92 | +2. `artists` are all the artists |
| 93 | +3. `tracks` are all the tracks, containing a column that tells us which album the track belongs to. |
| 94 | +4. `media_types` tell us what format a track is in, e.g., MP3, Apple Audio, etc. |
| 95 | +5. `genres` are a list of genres. |
| 96 | +6. `playlists` are, well, playlists. A play list has many tracks and a single track can belong to many playlists. |
| 97 | +7. `playlist_tracks` tells us which tracks belong to which playlists |
| 98 | + |
| 99 | +### Information About Customers and Their Orders |
| 100 | + |
| 101 | +1. `customers` are our customer records and they may or may not have an assigned "customer support representative" |
| 102 | +2. `invoices` are a list of specific customer orders |
| 103 | +3. `invoice_lines` are the line-items on specific invoices |
| 104 | + |
| 105 | +### Information About The Company |
| 106 | + |
| 107 | +1. `employees` contains information about our company's employees. This is mostly used to assign support representatives to customers. |
| 108 | + |
| 109 | +## One Key Idea |
| 110 | + |
| 111 | +One of the key ideas in how relational databases like SQLite3 and MySQL organize data is that we try to minimize redundancy by using references to other data rather than duplicating that data between different tables. |
| 112 | + |
| 113 | +For example, every track belongs to one (and only one) album. An album has its own associated information, like album title, publication date, and so on. Each track also has its own associated information, like track title, track position, and duration. We want to be able to ask questions like "What is the title of the album on which track X appears?" |
| 114 | + |
| 115 | +If you imagine a spreadsheet with a bunch of track listings, one way to achieve this would be to have an "Album Title" column and to answer this question we would just look at the value in the "Album Title" column for track X. Every track on the same album would have the same value in the "Album Title" column, although heaven help us if there are two separate albums with the same title! |
| 116 | + |
| 117 | +This is not how we store information in a relational database. Rather than storing album-related information in the same table as track-related information, we store album-related information in an "albums" table and track-related information in a "tracks" table. We assign each track and album a unique ID. In the "tracks" table we would when have an `album_id` column containing the unique album ID as a *reference* or *pointer* to the relevant row in the "albums" table. |
| 118 | + |
| 119 | +Excel can do this, but it is too cumbersome for the most common tasks. In a relational database like SQLite3 or MySQL, however, it is much easier to deal with. In fact, SQL (the language) is counting on you storing your data this way. |
0 commit comments