C4W4 — 資料庫與 SQL

本週核心問題:資安分析師如何用 SQL 從資料庫中快速查詢、過濾和合併資料,以支援安全決策?


一、資料庫基礎:資料怎麼存、怎麼找?

1.1 資料庫 vs 試算表

面向試算表(如 Google Sheets)資料庫
使用者單人或小團隊多人同時存取
資料量較少可儲存海量資料
處理能力基本可執行複雜查詢

1.2 關聯式資料庫

關聯式資料庫(relational database) = 包含多個彼此相關的表格的結構化資料庫。

表格結構:

概念說明類比
欄位(column / field)表格的直行,定義資料類型表頭:employee_id、username、department
列(row / record)一筆完整的資料紀錄一位員工的所有資訊

1.3 主鍵與外鍵

鍵類型定義規則數量限制
主鍵(primary key)每列都有唯一值的欄位不可重複、不可為空每個表格只有 1 個
外鍵(foreign key)在另一個表格中是主鍵的欄位可重複、可為空每個表格可有多個

實際範例

employees 表的 employee_id 是主鍵(每位員工有唯一 ID),machines 表的 employee_id 是外鍵(用來連結兩張表格)。


二、SQL 基礎:怎麼跟資料庫說話?

2.1 什麼是 SQL?

SQL(Structured Query Language) = 一種程式語言,用來建立、互動、查詢資料庫中的資料。

查詢(query) = 對資料庫表格提出的資料請求。

2.2 SQL 對資安分析師的價值

場景說明
搜尋 log從百萬筆登入紀錄中找出可疑的登入嘗試
更新管理找出還沒安裝最新修補程式的機器
維護排程根據使用量最低的時段安排機器更新時間
資料驅動決策用數據支持安全決策,向利害關係人報告

2.3 三種資料型別

型別說明範例查詢時用引號?
字串(string)有序字元序列'analyst10'、'USA'是,用單引號
數值(numeric)數字,可做數學運算1000、503否
日期時間(date and time)日期和/或時間'2023-01-15'、'18:00'是,用單引號

三、基本查詢:SELECT 與 FROM

3.1 核心語法

SELECT employee_id, device_id    -- 要看哪些欄位
FROM employees;                   -- 從哪張表格查

SQL 語法規則

  • 關鍵字不區分大小寫(SELECT = select),但慣例大寫方便閱讀
  • 表格名稱區分大小寫
  • 每條語句以分號 ; 結尾
  • 多個欄位用逗號分隔

3.2 選取所有欄位

SELECT *          -- * = 選取所有欄位
FROM employees;

3.3 排序:ORDER BY

SELECT customerid, city, country
FROM customers
ORDER BY city;              -- 預設升冪排序(A→Z、小→大)
用法說明
ORDER BY city升冪(預設):A→Z
ORDER BY city DESC降冪:Z→A
ORDER BY country, city先按 country 排,相同 country 再按 city 排

四、過濾查詢:WHERE

4.1 基本過濾

SELECT *
FROM log_in_attempts
WHERE country = 'USA';      -- 只回傳 country 等於 USA 的紀錄

4.2 比較運算子

運算子意義適用型別範例
=等於全部WHERE country = 'USA'
>大於 / 晚於數值、日期時間WHERE login_time > '18:00'
<小於 / 早於數值、日期時間WHERE login_date < '2023-01-15'
>=大於等於數值、日期時間WHERE birthdate >= '1970-01-01'
<=小於等於數值、日期時間
<> 或 !=不等於全部WHERE country <> 'USA'

> 是排他運算子(不含邊界值),>= 是包含運算子(含邊界值)

4.3 範圍過濾:BETWEEN

SELECT *
FROM machines
WHERE OS_patch_date BETWEEN '2021-03-01' AND '2021-09-01';
-- 回傳修補日期在 2021/3/1 到 2021/9/1 之間的機器(包含頭尾)

BETWEEN 是包含運算子,頭尾日期都會被包含在結果中。

4.4 模式比對:LIKE 與萬用字元

當你不知道完整值、只知道部分模式時,用 LIKE 取代 =。

兩個萬用字元:

萬用字元代表範例匹配結果
%零個或多個任意字元'East%'East-120、East-290
_恰好一個任意字元'N_'NY、NV、NS
-- 美國在資料庫中有 US 和 USA 兩種寫法,用 LIKE 一次抓到
SELECT *
FROM log_in_attempts
WHERE country LIKE 'US%';
模式匹配內容
'a%'以 a 開頭的任何字串
'%a'以 a 結尾的任何字串
'%a%'任何位置包含 a 的字串
'a_'a 後面恰好一個字元

五、複合過濾:AND、OR、NOT

5.1 三個邏輯運算子

運算子功能回傳條件
AND同時滿足兩個條件兩個條件都為真
OR滿足任一條件即可至少一個條件為真
NOT否定條件條件為假的紀錄

5.2 實際範例

-- AND:找同時使用 OS 1 且用 Email Client 1 的機器
SELECT *
FROM machines
WHERE operating_system = 'OS 1' AND email_client = 'Email Client 1';
 
-- OR:找使用 OS 1 或 OS 3 的機器(兩者都需要修補)
SELECT *
FROM machines
WHERE operating_system = 'OS 1' OR operating_system = 'OS 3';
 
-- NOT:找不是 OS 3 的所有機器
SELECT *
FROM machines
WHERE NOT operating_system = 'OS 3';

OR 的寫法

即使兩個條件都是同一個欄位,也要完整寫出兩次欄位名稱。 ✅ WHERE department = 'Finance' OR department = 'Sales' ❌ WHERE department = 'Finance' OR 'Sales'

組合使用:

-- 排除美國和加拿大的客戶
SELECT *
FROM customers
WHERE NOT country = 'Canada' AND NOT country = 'USA';

5.3 資安實戰範例

-- 找下班後(18:00 以後)的失敗登入嘗試
SELECT *
FROM log_in_attempts
WHERE login_time > '18:00' AND success = FALSE;
 
-- 找非墨西哥的登入嘗試(資料中有 MEX 和 MEXICO 兩種寫法)
SELECT *
FROM log_in_attempts
WHERE NOT country LIKE 'MEX%';

六、合併表格:JOIN

6.1 為什麼需要 JOIN?

單張表格通常只有部分資訊。例如 employees 有員工資料,machines 有機器資料。用 JOIN 把兩張表格合併,才能看到「哪位員工用哪台機器」的完整圖片。

6.2 table.column 語法

當兩張表格有相同的欄位名稱時,必須用 表格名.欄位名 來指定要用哪張表格的欄位:

employees.employee_id    -- employees 表的 employee_id
machines.employee_id     -- machines 表的 employee_id

6.3 四種 JOIN

JOIN 類型回傳內容不匹配的列
INNER JOIN只回傳兩張表格中匹配的列丟棄
LEFT JOIN左表(第一張)全部 + 右表匹配的列右表不匹配的欄位填 NULL
RIGHT JOIN右表(第二張)全部 + 左表匹配的列左表不匹配的欄位填 NULL
FULL OUTER JOIN兩張表格全部的列不匹配的欄位填 NULL

NULL = SQL 中代表「缺失值」的特殊值。

6.4 JOIN 語法

-- INNER JOIN:只回傳兩邊都有匹配的紀錄
SELECT username, office, operating_system
FROM employees                                           -- 左表
INNER JOIN machines                                      -- 右表
    ON employees.employee_id = machines.employee_id;     -- 匹配條件
 
-- LEFT JOIN:回傳所有機器,即使沒有分配給員工
SELECT *
FROM machines
LEFT JOIN employees ON machines.device_id = employees.device_id;
 
-- RIGHT JOIN:回傳所有員工,即使沒有分配到機器
SELECT *
FROM machines
RIGHT JOIN employees ON machines.device_id = employees.device_id;

LEFT JOIN 優先

實務上大多數分析師幾乎只用 LEFT JOIN,因為從左到右閱讀更直觀。 FROM A LEFT JOIN B 和 FROM B RIGHT JOIN A 結果完全相同,只要調換表格順序即可。

6.5 JOIN 三步驟口訣

  1. FROM:從哪張表格開始(左表)
  2. JOIN:加入哪張表格(右表)
  3. ON:用哪個欄位連接(左表.欄位 = 右表.欄位)

七、SQL vs Linux 過濾比較

面向LinuxSQL
用途檔案系統中搜尋檔案、管理權限、管理程序資料庫中查詢和操作結構化資料
結構自由格式,輸出為純文字行結構化,結果分欄清楚顯示
合併無法跨檔案合併資料可用 JOIN 合併多張表格
適用場景log 儲存為文字檔時資料儲存在資料庫中時

從 Linux 存取 SQL

在命令列輸入 sqlite3 可進入 SQLite,之後輸入的指令就是 SQL 語法而非 Linux 指令。


八、進階補充:聚合函數

聚合函數對多筆資料做計算,回傳單一結果值(不回傳原始資料)。

函數功能範例
COUNT()計算列數SELECT COUNT(firstname) FROM customers;
AVG()計算平均值SELECT AVG(salary) FROM employees;
SUM()計算總和SELECT SUM(total) FROM invoices;
-- 計算來自美國的客戶數量
SELECT COUNT(firstname)
FROM customers
WHERE country = 'USA';

九、術語速查表

術語定義
資料庫(Database)有組織的資料集合
日期時間資料(Date and time data)代表日期和/或時間的資料
排他運算子(Exclusive operator)不包含比較值的運算子(如 >)
過濾(Filtering)選取符合特定條件的資料
外鍵(Foreign key)在另一個表格中是主鍵的欄位
包含運算子(Inclusive operator)包含比較值的運算子(如 >=)
記錄檔(Log)組織系統中發生的事件紀錄
數值資料(Numeric data)由數字組成的資料
運算子(Operator)代表運算的符號或關鍵字
主鍵(Primary key)每列都有唯一值的欄位
查詢(Query)對資料庫表格的資料請求
關聯式資料庫(Relational database)包含彼此相關表格的結構化資料庫
字串資料(String data)由有序字元序列組成的資料
SQL(結構化查詢語言)用來建立、互動、查詢資料庫的程式語言
語法(Syntax)決定程式語言中什麼是正確結構的規則
萬用字元(Wildcard)可替代任何其他字元的特殊字元