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.
Data-Science-For-Beginners/translations/hk/2-Working-With-Data/05-relational-databases/README.md

193 lines
9.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "870a0086adbc313a8eea5489bdcb2522",
"translation_date": "2025-08-25T16:14:21+00:00",
"source_file": "2-Working-With-Data/05-relational-databases/README.md",
"language_code": "hk"
}
-->
# 使用數據:關係型數據庫
|![ 由 [(@sketchthedocs)](https://sketchthedocs.dev) 繪製的手繪筆記 ](../../sketchnotes/05-RelationalData.png)|
|:---:|
| 使用數據:關係型數據庫 - _手繪筆記由 [@nitya](https://twitter.com/nitya) 繪製_ |
你可能曾經使用過電子表格來存儲信息。電子表格由一組行和列組成,行包含信息(或數據),列描述這些信息(有時稱為元數據)。關係型數據庫正是基於這種表格中行和列的核心原則構建的,允許你將信息分散到多個表中。這樣可以處理更複雜的數據,避免重複,並且在探索數據時更加靈活。讓我們一起探索關係型數據庫的概念。
## [課前測驗](https://purple-hill-04aebfb03.1.azurestaticapps.net/quiz/8)
## 一切從表開始
關係型數據庫的核心是表。就像電子表格一樣,表是由列和行組成的集合。行包含我們希望處理的數據或信息,例如城市名稱或降雨量。列則描述它們存儲的數據。
讓我們從創建一個存儲城市信息的表開始探索。我們可能會從城市名稱和國家開始。你可以將其存儲在如下表格中:
| 城市 | 國家 |
| -------- | ------------- |
| 東京 | 日本 |
| 亞特蘭大 | 美國 |
| 奧克蘭 | 新西蘭 |
注意,**城市**、**國家**和**人口**這些列名描述了存儲的數據,而每一行則包含一個城市的信息。
## 單表方法的局限性
上述表格可能對你來說很熟悉。現在讓我們為這個初具規模的數據庫添加一些額外的數據——年度降雨量以毫米為單位。我們將關注2018年、2019年和2020年的數據。如果我們為東京添加數據可能會如下所示
| 城市 | 國家 | 年份 | 降雨量 |
| ----- | ------ | ---- | ------ |
| 東京 | 日本 | 2020 | 1690 |
| 東京 | 日本 | 2019 | 1874 |
| 東京 | 日本 | 2018 | 1445 |
你注意到這個表格有什麼問題嗎?你可能會發現我們重複了城市名稱和國家多次。這樣會佔用大量存儲空間,而且多次複製是沒有必要的。畢竟,東京只有一個名稱。
好吧,我們試試另一種方法。讓我們為每一年添加新的列:
| 城市 | 國家 | 2018 | 2019 | 2020 |
| -------- | ------------- | ---- | ---- | ---- |
| 東京 | 日本 | 1445 | 1874 | 1690 |
| 亞特蘭大 | 美國 | 1779 | 1111 | 1683 |
| 奧克蘭 | 新西蘭 | 1386 | 942 | 1176 |
雖然這樣避免了行的重複,但也帶來了一些其他挑戰。我們每次有新的一年時都需要修改表的結構。此外,隨著數據的增長,將年份作為列會使得檢索和計算數值變得更加困難。
這就是為什麼我們需要多個表和關係。通過將數據分解,我們可以避免重複,並且在處理數據時更加靈活。
## 關係的概念
讓我們回到數據,確定如何分解它。我們知道我們想要存儲城市的名稱和國家,因此這些信息最好存儲在一個表中。
| 城市 | 國家 |
| -------- | ------------- |
| 東京 | 日本 |
| 亞特蘭大 | 美國 |
| 奧克蘭 | 新西蘭 |
但在創建下一個表之前我們需要確定如何引用每個城市。我們需要某種形式的標識符、ID 或(在技術數據庫術語中)主鍵。主鍵是一個用於標識表中特定行的值。雖然這可以基於某個值本身(例如,我們可以使用城市名稱),但它幾乎總是應該是一個數字或其他標識符。我們不希望 ID 發生變化,因為這會破壞關係。在大多數情況下,主鍵或 ID 通常是一個自動生成的數字。
> ✅ 主鍵通常縮寫為 PK
### cities
| city_id | 城市 | 國家 |
| ------- | -------- | ------------- |
| 1 | 東京 | 日本 |
| 2 | 亞特蘭大 | 美國 |
| 3 | 奧克蘭 | 新西蘭 |
> ✅ 在本課程中,你會注意到我們交替使用 "id" 和 "主鍵" 這兩個術語。這些概念同樣適用於你稍後會探索的 DataFrames。雖然 DataFrames 不使用 "主鍵" 這一術語,但你會發現它們的行為非常相似。
有了我們的城市表,現在讓我們存儲降雨量。與其重複城市的完整信息,我們可以使用 ID。我們還應確保新創建的表也有一個 *id* 列,因為所有表都應該有一個 ID 或主鍵。
### rainfall
| 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 |
注意新創建的 **rainfall** 表中的 **city_id** 列。這一列包含的值引用了 **cities** 表中的 ID。在技術的關係型數據術語中這被稱為 **外鍵**;它是來自另一個表的主鍵。你可以將其視為一個引用或指針。**city_id** 1 指向東京。
> [!NOTE] 外鍵通常縮寫為 FK
## 檢索數據
將數據分成兩個表後,你可能會想知道如何檢索它。如果我們使用的是 MySQL、SQL Server 或 Oracle 等關係型數據庫我們可以使用一種稱為結構化查詢語言SQL的語言。SQL有時讀作 sequel是一種用於檢索和修改關係型數據庫中數據的標準語言。
要檢索數據,你可以使用命令 `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** 的數據結合起來。這可以通過*連接*它們來完成。你將在兩個表之間創建一個接縫,並匹配每個表中的某一列的值。
在我們的例子中,我們將匹配 **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
```
我們已經突出顯示了我們想要的兩列,以及我們希望通過 **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
```
## 總結
關係型數據庫的核心是將信息分割到多個表中,然後將其重新組合以進行顯示和分析。這提供了極高的靈活性來執行計算或以其他方式操作數據。你已經了解了關係型數據庫的核心概念,以及如何在兩個表之間執行連接。
## 🚀 挑戰
網絡上有許多關係型數據庫可供使用。你可以利用上面學到的技能來探索這些數據。
## 課後測驗
## [課後測驗](https://purple-hill-04aebfb03.1.azurestaticapps.net/quiz/9)
## 回顧與自學
[Microsoft Learn](https://docs.microsoft.com/learn?WT.mc_id=academic-77958-bethanycheum) 上有多種資源可供你繼續探索 SQL 和關係型數據庫的概念:
- [描述關係型數據的概念](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)
**免責聲明**
本文件已使用人工智能翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。雖然我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。原始語言的文件應被視為權威來源。對於重要信息,建議使用專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或錯誤解釋概不負責。