iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
IT Operation

Docker 新手村:從容器到 PostgreSQL 的實戰之路系列 第 28 篇

Day 27 - 設計員工與排班資料表:把專題資料放進 PostgreSQL

  • 分享至 

  • xImage
  •  

學習目標

  • 了解資料表設計的基本概念
  • 將員工與排班資料拆成不同 Table
  • 認識 Primary Key 與 Foreign Key
  • 建立 employees 與 schedules 資料表
  • 了解兩張資料表之間的關聯

從練習進入實際專題

前面已經學會建立 Database、Table,也可以透過 Node.js 連線 PostgreSQL。

今天要開始把這些內容應用到實際的排班專題。

排班系統最基本會需要兩種資料:

員工資料
排班資料

如果全部放在同一張 Table,之後資料增加時會變得不好管理。

因此可以拆成:

employees
   ↓
員工基本資料

schedules
   ↓
每天的排班資料

設計 employees 資料表

首先建立員工資料表:

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    employee_type VARCHAR(20) NOT NULL
);

這張 Table 負責保存:

id
name
employee_type

例如:

id name employee_type
1 小明 正職
2 小美 兼職
3 小華 正職

其中:

PRIMARY KEY

代表主鍵。

每一位員工都有自己唯一的 id,可以用來辨識不同員工。


設計 schedules 資料表

接著建立排班資料表:

CREATE TABLE schedules (
    id SERIAL PRIMARY KEY,
    employee_id INTEGER NOT NULL,
    work_date DATE NOT NULL,
    shift VARCHAR(20),
    FOREIGN KEY (employee_id)
        REFERENCES employees(id)
);

這張 Table 用來記錄每天的排班。

例如:

id employee_id work_date shift
1 1 2026-09-21 早班
2 2 2026-09-21 晚班
3 1 2026-09-22 晚班

其中 employee_id 就是用來表示這筆班表屬於哪一位員工。


Foreign Key 是什麼?

這次第一次使用:

FOREIGN KEY

也就是 外鍵。

在 schedules 中:

employee_id

會對應到:

employees(id)

關係可以畫成:

employees
────────────
id
name
employee_type
     │
     │ id
     ↓
schedules
────────────
employee_id
work_date
shift

因此不需要在每一筆排班資料中重複保存員工姓名,只需要保存員工的 id。


為什麼要拆成兩張 Table?

假設沒有拆開,每一筆排班都保存:

小明 / 正職 / 2026-09-21 / 早班
小明 / 正職 / 2026-09-22 / 晚班
小明 / 正職 / 2026-09-23 / 早班

員工姓名與類型就會一直重複。

拆開後:

employees

1 / 小明 / 正職

排班只需要:

1 / 2026-09-21 / 早班
1 / 2026-09-22 / 晚班
1 / 2026-09-23 / 早班

資料之間的關係也會更加清楚。


新增測試資料

先新增員工:

INSERT INTO employees (name, employee_type)
VALUES
('小明', '正職'),
('小美', '兼職');

接著新增排班:

INSERT INTO schedules (employee_id, work_date, shift)
VALUES
(1, '2026-09-21', '早班'),
(2, '2026-09-21', '晚班');

這樣員工與排班資料就已經產生關聯。


使用 JOIN 查詢排班

因為 schedules 只有保存 employee_id,如果想同時看到員工姓名,可以使用 JOIN:

SELECT
    employees.name,
    schedules.work_date,
    schedules.shift
FROM schedules
JOIN employees
ON schedules.employee_id = employees.id;

查詢結果可能會像:

name | work_date  | shift
-----+------------+------
小明 | 2026-09-21 | 早班
小美 | 2026-09-21 | 晚班

這樣就能把兩張 Table 的資料組合起來。


目前的資料庫架構

做到這裡,排班系統的基本資料架構已經出現:

schedule_db
│
├── employees
│     ├── id
│     ├── name
│     └── employee_type
│
└── schedules
      ├── id
      ├── employee_id
      ├── work_date
      └── shift

其中:

employees.id
      ↓
schedules.employee_id

透過 Foreign Key 建立兩張資料表之間的關係。


常見錯誤與修正

  • ❌ 所有資料全部放在同一張 Table → ✅ 依照資料用途拆分
  • ❌ 每筆排班重複保存員工資料 → ✅ 使用 employee_id 建立關聯
  • ❌ Foreign Key 對應錯誤 → ✅ 確認對應 employees(id)
  • ❌ 新增不存在的 employee_id → ✅ 先確認員工資料存在
  • ❌ JOIN 後資料不正確 → ✅ 確認 ON 後面的關聯欄位

今日小挑戰(可交付)

  • [ ] 建立 employees Table
  • [ ] 建立 schedules Table
  • [ ] 替兩張 Table 設定 Primary Key
  • [ ] 使用 Foreign Key 建立關聯
  • [ ] 新增兩位測試員工
  • [ ] 新增兩筆排班資料
  • [ ] 使用 JOIN 查詢員工姓名與班別

DAY27 心得

今天開始把 PostgreSQL 真正套用到自己的排班專題,不再只是建立單一 Table 練習 SQL,而是開始思考不同資料之間應該怎麼設計。

原本如果直接把員工姓名、職位、日期和班別全部存在一起,看起來比較簡單,但資料多了之後就會一直重複。把員工和排班拆成兩張 Table,再透過 employee_id 和 Foreign Key 建立關係後,整體結構清楚很多。

今天也第一次實際使用 JOIN,把兩張 Table 的資料重新組合起來。下一步就可以讓 Node.js API 操作這些資料,讓前端不需要直接接觸 PostgreSQL,也能完成員工資料的新增與查詢。


上一篇
Day 26 - 環境變數與 .env:不要把資料庫密碼寫死在程式裡
下一篇
Day 28 - Node.js API 串接 PostgreSQL:讓前端可以存取資料庫
系列文
Docker 新手村:從容器到 PostgreSQL 的實戰之路 共 31 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言