14. Why Tables Join: Keys and Relationships
14.1 Primary Key and Foreign Key in Plain English
Why. Company data is split across many tables so that each fact is stored once. Keys are how you find which rows in one table belong to rows in another.
What. A row is one record, such as one hub, and a column is one detail about it, such as its city. A primary key is a column whose value is different for every row, like hub_id in hubs. A foreign key is a column in another table that stores that value to point back, like hub_id in shipments. In SQLite, foreign key checks are usually off by default, but the way SQLite was built can change that. So run PRAGMA foreign_keys to see the current setting. If you need the checks, run PRAGMA foreign_keys = ON on each connection before you start a transaction, because the setting cannot be changed inside one.
How. Look at the hubs table, then at the hub_id column in shipments, and check the foreign key setting.
Steps
- Run the first example and see that every hub_id appears once.
- Run the second example and see hub_id repeated in shipments.
- Run PRAGMA foreign_keys; a result of 0 means the checks are off for this connection, and 1 means they are on.
- Remember that the key names do not have to match, but the values do.
Examples
Example 1 · dataset: swiftship_logistics
SELECT hub_id, hub_code, city, currency
FROM hubs
ORDER BY hub_id;Output
| hub_id | hub_code | city | currency |
|---|---|---|---|
| 1 | PNQ-01 | Pune | INR |
| 2 | BOM-02 | Mumbai | INR |
| 3 | DXB-01 | Dubai | AED |
| 4 | LHR-03 | London | GBP |
| 5 | SIN-01 | Singapore | SGD |
Meaning. Each row is one hub, and each hub_id appears only once. That is why hub_id can be the primary key of hubs.
Example 2 · dataset: swiftship_logistics
SELECT shipment_id, hub_id, tracking_code
FROM shipments
ORDER BY shipment_id;Output
| shipment_id | hub_id | tracking_code |
|---|---|---|
| 1001 | 1 | PNQ-01-00017 |
| 1002 | 1 | PNQ-01-00018 |
| 1003 | 2 | BOM-02-00102 |
| 1004 | 3 | DXB-01-00009 |
| 1005 | 3 | DXB-01-00010 |
| 1006 | 4 | LHR-03-00221 |
| 1007 | 1 | PNQ-01-00019 |
| 1008 | 2 | BOM-02-00103 |
| 1009 | 9 | LHR-03-00222 |
| 1010 | NULL | PNQ-01-00020 |
Meaning. Hub 1 appears in several shipments, because one hub sends many parcels. Shipment 1009 points to hub 9, which is not in hubs, and 1010 has no hub yet.
Example 3 · dataset: swiftship_logistics
PRAGMA foreign_keys;Output
| foreign_keys |
|---|
| 0 |
Meaning. The result 0 means SQLite is not checking foreign keys on this connection. With the checks off, a wrong value like hub 9 can be saved.
Ravindra Bagale's Tip
Never assume a key is unique because of its name. Check it with COUNT(*) and COUNT(DISTINCT key), and look for NULLs, as shown in lesson 14.3.
Ravindra Bagale's Tip – मराठी
नावावरून key unique आहे असं कधीच मानू नका. Lesson 14.3 मध्ये दाखवल्याप्रमाणे COUNT(*) आणि COUNT(DISTINCT key) ने तपासा, आणि NULLs सुद्धा शोधा.
Ravindra Bagale's Tip – हिंदी
नाम देखकर key को unique मत मानिए। Lesson 14.3 की तरह COUNT(*) और COUNT(DISTINCT key) से जाँचिए, और NULLs भी देखिए।