Temporary tables(臨時表)就是只在你這次 session 或 transaction 裡存在的表。等你 session 結束(或 transaction close)後,這個 temporary table 跟裡面的資料就會像沙灘上的腳印一樣消失啦。這種表超適合暫存資料、中間運算,或是先把資料準備好再做複雜操作。
那到底有啥用?
- 暫存資料:比如你有一堆複雜的計算要分幾步做,這時就不用一直動到主表,直接用 temporary tables 就好。
- 資料分析:你可以把不同來源的資料先收集起來、處理完,分析完再把 temporary table 刪掉。
- 優化複雜查詢:有時候把查詢拆幾步,用 temporary tables 存中間結果,速度會快很多。
- 降低風險:不用怕不小心搞壞真的表,temporary tables 完全隔離,超安全。
temporary tables 的魔法就是,只有你自己看得到裡面的資料!其他 database user 完全看不到,超適合拿來亂搞實驗。
怎麼創 temporary tables
創 temporary table 跟創一般表差不多,只是要加個 TEMP 或 TEMPORARY 關鍵字。
語法:
CREATE TEMP TABLE table_name (
column_name data_type constraints,
...
);
是不是超簡單?temporary table 會在你 session 結束時自動消失。
舉個例子,來創一個暫存學生資料的 temporary table:
CREATE TEMP TABLE temp_students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER CHECK (age > 0)
);
現在我們有個 temporary table temp_students,可以像一般表一樣 insert 資料、查詢啥的。只是記得,session 關掉它就不見啦。
用查詢直接創 temporary table
有時候你懶得自己寫 temporary table 結構,尤其只是想把某個查詢結果存下來再用。這時可以這樣:
CREATE TEMP TABLE 表名 AS
SELECT ...;
這招不只會創 temporary table,還會 直接把查詢結果塞進去。
假設你想把還沒選課的學生存下來:
CREATE TEMP TABLE temp_unregistered_students AS
SELECT s.id, s.name
FROM students s
LEFT JOIN enrollments e ON s.id = e.student_id
WHERE e.student_id IS NULL;
現在你有個 temp_unregistered_students 表,可以在 script 其他地方用,不用一直重複查詢。
為啥要這樣?
- 不用自己寫 columns 跟型別,PostgreSQL 會自動從
SELECT結果判斷。 - 可以重複用這些暫存資料,不用每次都重新算。
- 這在報表、ETL 跟分析時超方便。
transaction 裡的 temporary tables
temporary tables 也可以在 transaction 裡創。這樣的話,transaction 結束時它們會自動被刪掉。這對於你想確保暫存資料不會殘留在資料庫裡的情境超有用。transaction 的細節我之後還會講,現在先爽爽用 temporary tables 吧 :P
範例:
BEGIN;
CREATE TEMP TABLE temp_transactions (
transaction_id SERIAL PRIMARY KEY,
amount NUMERIC(10, 2) NOT NULL,
status VARCHAR(50)
);
INSERT INTO temp_transactions (amount, status)
VALUES (100.50, '等待中');
-- 來看看資料
SELECT * FROM temp_transactions;
COMMIT;
-- 現在 temp_transactions 表已經消失啦!
如果你不是用 COMMIT,而是 ROLLBACK,資料跟表也會一起消失。
temporary tables 在實戰裡怎麼用
範例 1:暫時合併資料
假設我們有兩個表:students 跟 courses。要找出哪些學生還沒選課,可以先把資料收進 temporary table,再分析。
CREATE TEMP TABLE temp_unregistered_students AS
SELECT s.id, s.name
FROM students s
LEFT JOIN enrollments e ON s.id = e.student_id
WHERE e.student_id IS NULL;
-- 現在可以用 temp_unregistered_students 這個 temporary table 來查資料。
SELECT * FROM temp_unregistered_students;
範例 2:準備報表資料
有時候要從好幾個表抓資料、轉換一下,最後做成報表。temporary tables 超適合這種情境。
CREATE TEMP TABLE temp_sales AS
SELECT p.product_id, p.name, SUM(s.quantity) AS total_quantity
FROM products p
JOIN sales s ON p.product_id = s.product_id
GROUP BY p.product_id, p.name;
-- 創好 temporary table 之後,就可以直接拿來做報表啦:
SELECT name, total_quantity FROM temp_sales WHERE total_quantity > 50;
temporary tables 的小技巧跟注意事項
temporary table 命名:如果你已經有個叫 students 的一般表,還是可以創 temporary table 叫一樣的名字!在你 session 裡 temporary table 會優先。不過這樣有時候會搞混,記得自己現在用的是哪個表。
temporary table 優化:PostgreSQL 會自動幫有 PRIMARY KEY 或 UNIQUE 限制的欄位創 index,就算是 temporary table 也一樣。如果你想再快一點,也可以自己加 index:
CREATE INDEX idx_temp_students_age ON temp_students (age);
刪 temporary table:如果你想在 session 結束前就刪掉 temporary table,用 DROP TABLE:
DROP TABLE temp_students;
temporary table 的資料量:temporary tables 通常會存在記憶體裡(如果資源夠),所以速度很快。但如果資料太大,還是會寫到硬碟喔。
常見錯誤跟怎麼避免
錯誤 1:「表已經存在」
如果你想創 temporary table,但名字跟現有 temporary table 一樣,會報錯。可以用 CREATE TEMP TABLE IF NOT EXISTS,或是先刪掉再創:
DROP TABLE IF EXISTS temp_students;
CREATE TEMP TABLE temp_students (...);
錯誤 2:「表太早消失」
如果你在 transaction 裡創 temporary table,記得 transaction 結束時它就會消失。要先想好流程喔!
GO TO FULL VERSION