# データの取り扱い: リレーショナルデータベース |![ Sketchnote by [(@sketchthedocs)](https://sketchthedocs.dev) ](../../sketchnotes/05-RelationalData.png)| |:---:| | データの取り扱い: リレーショナルデータベース - _スケッチノート by [@nitya](https://twitter.com/nitya)_ | 過去にスプレッドシートを使って情報を保存したことがあるかもしれません。スプレッドシートには行と列があり、行には情報(データ)が含まれ、列はその情報を説明します(メタデータと呼ばれることもあります)。リレーショナルデータベースは、この行と列のテーブルという基本原則に基づいて構築されており、情報を複数のテーブルに分散させることができます。これにより、より複雑なデータを扱い、重複を避け、データを探索する方法に柔軟性を持たせることができます。それでは、リレーショナルデータベースの概念を探ってみましょう。 ## [講義前クイズ](https://ff-quizzes.netlify.app/en/ds/quiz/8) ## すべてはテーブルから始まる リレーショナルデータベースの中心にはテーブルがあります。スプレッドシートと同様に、テーブルは列と行の集合です。行には、都市名や降雨量など、扱いたいデータや情報が含まれています。列は保存されるデータを説明します。 まず、都市に関する情報を保存するテーブルを作成することから始めましょう。都市名と国名を保存するところから始めることができます。この情報を以下のようなテーブルに保存できます。 | 都市 | 国 | | ---------- | ------------ | | 東京 | 日本 | | アトランタ | アメリカ合衆国 | | オークランド | ニュージーランド | **都市**、**国**、**人口**という列名が保存されるデータを説明していることに注目してください。そして、各行には1つの都市に関する情報が含まれています。 ## 単一テーブルアプローチの欠点 上記のテーブルは比較的馴染み深いものに見えるかもしれません。それでは、成長するデータベースに年間降雨量(ミリメートル単位)という追加データを加えてみましょう。2018年、2019年、2020年のデータに焦点を当てます。東京のデータを追加すると、次のようになります。 | 都市 | 国 | 年 | 降雨量 | | ------ | ------ | ---- | ------ | | 東京 | 日本 | 2020 | 1690 | | 東京 | 日本 | 2019 | 1874 | | 東京 | 日本 | 2018 | 1445 | このテーブルについて何か気づきましたか?都市名と国名を何度も繰り返していることに気づくかもしれません。これではかなりのストレージを消費し、必要以上に重複してしまいます。結局のところ、東京には私たちが興味を持つ名前は1つしかありません。 では、別の方法を試してみましょう。各年のデータを新しい列として追加してみます。 | 都市 | 国 | 2018 | 2019 | 2020 | | ---------- | ------------ | ---- | ---- | ---- | | 東京 | 日本 | 1445 | 1874 | 1690 | | アトランタ | アメリカ合衆国 | 1779 | 1111 | 1683 | | オークランド | ニュージーランド | 1386 | 942 | 1176 | これにより行の重複は避けられますが、いくつかの課題が生じます。新しい年が追加されるたびにテーブルの構造を変更する必要があります。また、データが増えるにつれて、年を列として扱うと値の取得や計算が難しくなります。 これが、複数のテーブルとリレーションシップが必要な理由です。データを分割することで重複を避け、データを扱う際の柔軟性を高めることができます。 ## リレーションシップの概念 データに戻り、どのように分割するかを決定しましょう。都市名と国名を保存したいことはわかっているので、これらは1つのテーブルに保存するのが最適です。 | 都市 | 国 | | ---------- | ------------ | | 東京 | 日本 | | アトランタ | アメリカ合衆国 | | オークランド | ニュージーランド | しかし、次のテーブルを作成する前に、各都市を参照する方法を考える必要があります。何らかの識別子、ID、または(技術的なデータベース用語で)主キーが必要です。主キーは、テーブル内の特定の行を識別するために使用される値です。これが値そのものに基づいている場合(例えば都市名を使用することもできます)、ほとんどの場合、番号やその他の識別子であるべきです。IDが変更されるとリレーションシップが壊れるため、変更されないものが望ましいです。ほとんどの場合、主キーやIDは自動生成された番号になります。 > ✅ 主キーは頻繁にPKと略されます ### 都市テーブル | city_id | 都市 | 国 | | ------- | ---------- | ------------ | | 1 | 東京 | 日本 | | 2 | アトランタ | アメリカ合衆国 | | 3 | オークランド | ニュージーランド | > ✅ このレッスンでは「id」と「主キー」という用語を同じ意味で使用していることに注意してください。ここでの概念は、後で学ぶDataFrameにも適用されます。DataFrameでは「主キー」という用語は使用されませんが、ほぼ同じように動作することに気づくでしょう。 都市テーブルが作成されたので、降雨量を保存しましょう。都市に関する完全な情報を重複させるのではなく、IDを使用します。また、新しく作成されたテーブルにも*id*列を追加する必要があります。すべてのテーブルにはIDまたは主キーが必要です。 ### 降雨量テーブル | rainfall_id | city_id | 年 | 降雨量 | | ----------- | ------- | ---- | ------ | | 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 | 新しく作成された**降雨量**テーブル内の**city_id**列に注目してください。この列には、**都市**テーブル内のIDを参照する値が含まれています。技術的なリレーショナルデータ用語では、これを**外部キー**と呼びます。他のテーブルの主キーです。単に参照またはポインタと考えることができます。**city_id** 1は東京を参照しています。 > [!NOTE] 外部キーは頻繁にFKと略されます ## データの取得 データを2つのテーブルに分割したことで、どのようにデータを取得するのか疑問に思うかもしれません。MySQL、SQL Server、Oracleなどのリレーショナルデータベースを使用している場合、Structured Query Language(SQL)と呼ばれる言語を使用できます。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 ``` ## データの結合 これまで、単一のテーブルからデータを取得してきました。次は、**都市**と**降雨量**の両方のデータを結びつけたいと思います。これは、*結合*することで実現します。2つのテーブルの間に「縫い目」を作り、それぞれのテーブルの列の値を一致させます。 この例では、**降雨量**の**city_id**列と**都市**の**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://ff-quizzes.netlify.app/en/ds/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)を使用して翻訳されています。正確性を追求しておりますが、自動翻訳には誤りや不正確な部分が含まれる可能性があります。元の言語で記載された文書が正式な情報源とみなされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤解釈について、当社は責任を負いません。