|
|
<!--
|
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
|
{
|
|
|
"original_hash": "870a0086adbc313a8eea5489bdcb2522",
|
|
|
"translation_date": "2025-08-25T16:15:36+00:00",
|
|
|
"source_file": "2-Working-With-Data/05-relational-databases/README.md",
|
|
|
"language_code": "ja"
|
|
|
}
|
|
|
-->
|
|
|
# データの操作: リレーショナルデータベース
|
|
|
|
|
|
| ](../../sketchnotes/05-RelationalData.png)|
|
|
|
|:---:|
|
|
|
| データの操作: リレーショナルデータベース - _スケッチノート by [@nitya](https://twitter.com/nitya)_ |
|
|
|
|
|
|
過去にスプレッドシートを使って情報を保存したことがあるかもしれません。スプレッドシートには行と列があり、行には情報(データ)が、列にはその情報を説明する内容(メタデータと呼ばれることもあります)が含まれています。リレーショナルデータベースは、この行と列のテーブルという基本原則に基づいて構築されており、複数のテーブルに情報を分散させることができます。これにより、より複雑なデータを扱い、重複を避け、データを柔軟に探索することが可能になります。それでは、リレーショナルデータベースの概念を見ていきましょう。
|
|
|
|
|
|
## [講義前クイズ](https://purple-hill-04aebfb03.1.azurestaticapps.net/quiz/8)
|
|
|
|
|
|
## すべてはテーブルから始まる
|
|
|
|
|
|
リレーショナルデータベースの中心にはテーブルがあります。スプレッドシートと同様に、テーブルは列と行の集合です。行には、都市名や降水量など、扱いたいデータや情報が含まれています。列は、保存されるデータを説明します。
|
|
|
|
|
|
都市に関する情報を保存するテーブルを作成するところから始めましょう。都市名と国名を保存することから始めると、次のようなテーブルを作成できます。
|
|
|
|
|
|
| City | Country |
|
|
|
| -------- | ------------- |
|
|
|
| Tokyo | Japan |
|
|
|
| Atlanta | United States |
|
|
|
| Auckland | New Zealand |
|
|
|
|
|
|
**city**、**country**、**population** という列名が保存されるデータを説明しており、各行には1つの都市に関する情報が含まれています。
|
|
|
|
|
|
## 単一テーブルアプローチの欠点
|
|
|
|
|
|
上記のテーブルは、比較的馴染みのあるものに見えるかもしれません。では、成長中のデータベースに年間降水量(ミリメートル単位)を追加してみましょう。2018年、2019年、2020年のデータに焦点を当てます。東京のデータを追加すると、次のようになります。
|
|
|
|
|
|
| City | Country | Year | Amount |
|
|
|
| ----- | ------- | ---- | ------ |
|
|
|
| Tokyo | Japan | 2020 | 1690 |
|
|
|
| Tokyo | Japan | 2019 | 1874 |
|
|
|
| Tokyo | Japan | 2018 | 1445 |
|
|
|
|
|
|
このテーブルで何に気づきますか?都市名と国名が何度も繰り返されていることに気づくかもしれません。これはかなりのストレージを消費し、複数のコピーを持つ必要がないため、非効率的です。結局のところ、東京には私たちが興味を持つ名前は1つだけです。
|
|
|
|
|
|
では、別の方法を試してみましょう。各年のデータを新しい列として追加してみます。
|
|
|
|
|
|
| City | Country | 2018 | 2019 | 2020 |
|
|
|
| -------- | ------------- | ---- | ---- | ---- |
|
|
|
| Tokyo | Japan | 1445 | 1874 | 1690 |
|
|
|
| Atlanta | United States | 1779 | 1111 | 1683 |
|
|
|
| Auckland | New Zealand | 1386 | 942 | 1176 |
|
|
|
|
|
|
これにより行の重複は避けられますが、他の課題が発生します。新しい年が追加されるたびにテーブルの構造を変更する必要があります。また、データが増えるにつれて、年を列として扱うと値の取得や計算が難しくなります。
|
|
|
|
|
|
これが、複数のテーブルとリレーションシップが必要な理由です。データを分割することで、重複を避け、データを操作する際の柔軟性を高めることができます。
|
|
|
|
|
|
## リレーションシップの概念
|
|
|
|
|
|
データに戻り、どのように分割するかを決定しましょう。都市の名前と国名を保存したいことはわかっているので、これは1つのテーブルにまとめるのが最適です。
|
|
|
|
|
|
| City | Country |
|
|
|
| -------- | ------------- |
|
|
|
| Tokyo | Japan |
|
|
|
| Atlanta | United States |
|
|
|
| Auckland | New Zealand |
|
|
|
|
|
|
しかし、次のテーブルを作成する前に、各都市を参照する方法を考える必要があります。何らかの識別子、ID、または(技術的なデータベース用語で言うと)主キーが必要です。主キーは、テーブル内の特定の行を識別するために使用される値です。これは値自体に基づく場合もあります(たとえば、都市名を使用することもできます)が、ほとんどの場合、数値やその他の識別子であるべきです。IDが変更されるとリレーションシップが壊れるためです。ほとんどの場合、主キーやIDは自動生成される数値になります。
|
|
|
|
|
|
> ✅ 主キーは「PK」と略されることがよくあります
|
|
|
|
|
|
### cities
|
|
|
|
|
|
| city_id | City | Country |
|
|
|
| ------- | -------- | ------------- |
|
|
|
| 1 | Tokyo | Japan |
|
|
|
| 2 | Atlanta | United States |
|
|
|
| 3 | Auckland | New Zealand |
|
|
|
|
|
|
> ✅ このレッスンでは、「id」と「主キー」という用語を同じ意味で使用します。ここでの概念は、後で学ぶDataFrameにも適用されます。DataFrameでは「主キー」という用語は使用されませんが、ほぼ同じように動作することに気づくでしょう。
|
|
|
|
|
|
都市のテーブルが作成されたので、降水量を保存しましょう。都市に関する完全な情報を重複させる代わりに、IDを使用します。また、新しく作成したテーブルにも*id*列を追加する必要があります。すべてのテーブルにはIDまたは主キーが必要です。
|
|
|
|
|
|
### rainfall
|
|
|
|
|
|
| rainfall_id | city_id | Year | Amount |
|
|
|
| ----------- | ------- | ---- | ------ |
|
|
|
| 1 | 1 | 2018 | 1445 |
|
|
|
| 2 | 1 | 2019 | 1874 |
|
|
|
| 3 | 1 | 2020 | 1690 |
|
|
|
| 4 | 2 | 2018 | 1779 |
|
|
|
| 5 | 2 | 2019 | 1111 |
|
|
|
| 6 | 2 | 2020 | 1683 |
|
|
|
| 7 | 3 | 2018 | 1386 |
|
|
|
| 8 | 3 | 2019 | 942 |
|
|
|
| 9 | 3 | 2020 | 1176 |
|
|
|
|
|
|
新しく作成した**rainfall**テーブル内の**city_id**列に注目してください。この列には、**cities**テーブル内のIDを参照する値が含まれています。技術的なリレーショナルデータ用語では、これを**外部キー**と呼びます。他のテーブルの主キーです。単に参照またはポインタと考えることができます。**city_id** 1は東京を参照しています。
|
|
|
|
|
|
> [!NOTE] 外部キーは「FK」と略されることがよくあります
|
|
|
|
|
|
## データの取得
|
|
|
|
|
|
データを2つのテーブルに分割した状態で、どのようにデータを取得するのか疑問に思うかもしれません。MySQL、SQL Server、Oracleなどのリレーショナルデータベースを使用している場合、SQL(Structured Query Language)と呼ばれる言語を使用します。SQL(シークエルと発音されることもあります)は、リレーショナルデータベース内のデータを取得および変更するための標準言語です。
|
|
|
|
|
|
データを取得するには、`SELECT`コマンドを使用します。基本的には、**表示したい列を選択し**、それらが含まれるテーブルを**指定**します。都市名だけを表示したい場合、次のように記述します。
|
|
|
|
|
|
```sql
|
|
|
SELECT city
|
|
|
FROM cities;
|
|
|
|
|
|
-- Output:
|
|
|
-- Tokyo
|
|
|
-- Atlanta
|
|
|
-- Auckland
|
|
|
```
|
|
|
|
|
|
`SELECT`は表示したい列をリストし、`FROM`はテーブルをリストします。
|
|
|
|
|
|
> [NOTE] SQLの構文は大文字小文字を区別しません。つまり、`select`と`SELECT`は同じ意味です。ただし、使用しているデータベースの種類によっては、列名やテーブル名が大文字小文字を区別する場合があります。そのため、プログラミングではすべてを大文字小文字を区別するものとして扱うのがベストプラクティスです。SQLクエリを書く際の一般的な慣習として、キーワードはすべて大文字で記述します。
|
|
|
|
|
|
上記のクエリはすべての都市を表示します。ニュージーランドの都市だけを表示したいと想像してみてください。何らかのフィルターが必要です。SQLのキーワードでこれを行うのが`WHERE`、つまり「条件が真である場合」です。
|
|
|
|
|
|
```sql
|
|
|
SELECT city
|
|
|
FROM cities
|
|
|
WHERE country = 'New Zealand';
|
|
|
|
|
|
-- Output:
|
|
|
-- Auckland
|
|
|
```
|
|
|
|
|
|
## データの結合
|
|
|
|
|
|
これまで、単一のテーブルからデータを取得してきました。次に、**cities**と**rainfall**の両方からデータを結合して取得します。これは、*結合*することで実現します。2つのテーブルの間にシームを作成し、それぞれのテーブルの列の値を一致させます。
|
|
|
|
|
|
この例では、**rainfall**の**city_id**列と**cities**の**city_id**列を一致させます。これにより、降水量の値がそれぞれの都市と一致します。ここで行う結合の種類は、*内部結合*と呼ばれるもので、他のテーブルと一致しない行は表示されません。この場合、すべての都市に降水量データがあるため、すべてが表示されます。
|
|
|
|
|
|
すべての都市の2019年の降水量を取得してみましょう。
|
|
|
|
|
|
これを段階的に行います。最初のステップは、**city_id**列を指定してデータを結合することです。
|
|
|
|
|
|
```sql
|
|
|
SELECT cities.city
|
|
|
rainfall.amount
|
|
|
FROM cities
|
|
|
INNER JOIN rainfall ON cities.city_id = rainfall.city_id
|
|
|
```
|
|
|
|
|
|
結合したい2つの列と、**city_id**でテーブルを結合したいことを指定しました。次に、`WHERE`文を追加して2019年のデータだけをフィルタリングします。
|
|
|
|
|
|
```sql
|
|
|
SELECT cities.city
|
|
|
rainfall.amount
|
|
|
FROM cities
|
|
|
INNER JOIN rainfall ON cities.city_id = rainfall.city_id
|
|
|
WHERE rainfall.year = 2019
|
|
|
|
|
|
-- Output
|
|
|
|
|
|
-- city | amount
|
|
|
-- -------- | ------
|
|
|
-- Tokyo | 1874
|
|
|
-- Atlanta | 1111
|
|
|
-- Auckland | 942
|
|
|
```
|
|
|
|
|
|
## まとめ
|
|
|
|
|
|
リレーショナルデータベースは、情報を複数のテーブルに分割し、それを表示や分析のために再結合することを中心にしています。これにより、計算を行ったり、データを操作したりする際に高い柔軟性が得られます。リレーショナルデータベースの基本概念と、2つのテーブル間で結合を行う方法を学びました。
|
|
|
|
|
|
## 🚀 チャレンジ
|
|
|
|
|
|
インターネット上には多数のリレーショナルデータベースがあります。ここで学んだスキルを使ってデータを探索してみてください。
|
|
|
|
|
|
## 講義後クイズ
|
|
|
|
|
|
## [講義後クイズ](https://purple-hill-04aebfb03.1.azurestaticapps.net/quiz/9)
|
|
|
|
|
|
## 復習と自己学習
|
|
|
|
|
|
SQLやリレーショナルデータベースの概念をさらに探求するために、[Microsoft Learn](https://docs.microsoft.com/learn?WT.mc_id=academic-77958-bethanycheum)にはいくつかのリソースがあります。
|
|
|
|
|
|
- [リレーショナルデータの概念を説明する](https://docs.microsoft.com//learn/modules/describe-concepts-of-relational-data?WT.mc_id=academic-77958-bethanycheum)
|
|
|
- [Transact-SQLでクエリを始める](https://docs.microsoft.com//learn/paths/get-started-querying-with-transact-sql?WT.mc_id=academic-77958-bethanycheum)(Transact-SQLはSQLのバージョンです)
|
|
|
- [Microsoft LearnのSQLコンテンツ](https://docs.microsoft.com/learn/browse/?products=azure-sql-database%2Csql-server&expanded=azure&WT.mc_id=academic-77958-bethanycheum)
|
|
|
|
|
|
## 課題
|
|
|
|
|
|
[課題タイトル](assignment.md)
|
|
|
|
|
|
**免責事項**:
|
|
|
この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があることをご承知ください。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当方は一切の責任を負いません。 |