想像一下,你又要幫大學建學生表格啦。又來了! :)
一開始你決定年齡欄位 age 用整數型別,設成 SMALLINT(適合 -32,768 到 32,767 的數字)。但過一陣子,資料庫越來越大,你還加了來自其他國家的學生,他們的年齡是...用天數算的!這時 SMALLINT 就不夠用了——該換成 INTEGER 之類的型別啦。
還有幾個常見的情境,會需要改資料型別:
- 數字範圍要變大或變小。
- 字串長度要調整(比如從
VARCHAR(50)換成VARCHAR(100))。 - 為了優化,換成別的資料型別(像把
TEXT轉成VARCHAR)。 - 一開始選錯型別(例如你填了
BOOLEAN,其實該用INTEGER)。
更改資料型別的語法
在 PostgreSQL 裡,要改欄位的資料型別就是用 ALTER TABLE。這樣可以讓表格結構跟著需求變動。
ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type;
很簡單啦:指定表格名稱、要改的欄位,還有新型別就好。
範例 1:從 INTEGER 換成 BIGINT
假設我們有個學生表:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER
);
一切都很順,直到年齡超過百萬歲(別問,純粹舉例啦!)。為了讓 PostgreSQL 不要崩潰,我們把 age 從 INTEGER 換成 BIGINT:
ALTER TABLE students
ALTER COLUMN age TYPE BIGINT;
範例 2:增加字串長度
你建了一個課程表,課程名稱最多 50 個字:
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
結果發現課程名稱比你想像的還要長又複雜。這問題很好解決:
ALTER TABLE courses
ALTER COLUMN name TYPE VARCHAR(150);
範例 3:型別轉換
假設有個表,birth_date 欄位本來是文字:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
birth_date TEXT
);
你發現用 TEXT 存日期很難查詢或排序。怎麼辦?把 TEXT 轉成 DATE:
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING birth_date::DATE;
注意 USING birth_date::DATE 這段。這是告訴 PostgreSQL 要先轉換資料再改型別。
為什麼有時候要明確轉換資料?
當 PostgreSQL 遇到型別變更時,會試著自動把現有資料轉成新型別。如果不行,就會報錯。比如把 TEXT 直接改成 INTEGER,沒說怎麼轉,肯定失敗。
問題範例
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- 錯誤:無法將值 'not a date' 轉成 DATE 型別。
這問題有解。加上明確的轉換方式,用 USING:
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE USING to_date(birth_date, 'YYYY-MM-DD');
這裡我們用 to_date() 函數,把字串轉成日期格式。
USING 指令
在 PostgreSQL 裡,當你用 ALTER TABLE ... ALTER COLUMN ... TYPE 改型別時,有時候要 指定怎麼轉換現有資料——這時就要用 USING 關鍵字。
語法:
ALTER TABLE table_name
ALTER COLUMN column_name TYPE new_data_type
USING expression;
說明:
USING讓你明確指定 從舊型別轉新型別的轉換公式。- 這在 自動轉換不行或不明確 時特別有用。
簡單範例:字串 → 數字
ALTER TABLE users
ALTER COLUMN age TYPE INTEGER
USING age::INTEGER;
這裡 age 原本是 TEXT,我們要轉成 INTEGER。USING age::INTEGER 就是明確型別轉換。
範例:文字 → 日期
ALTER TABLE events
ALTER COLUMN event_date TYPE DATE
USING TO_DATE(event_date, 'YYYY-MM-DD');
如果 event_date 是像 '2023-10-25' 這樣的字串,我們就告訴 PostgreSQL 怎麼把它變成 DATE 型別。
什麼時候 USING 必須要用?
- 當 沒有直接型別轉換。
- 當資料需要 轉換格式。
- 當型別不相容(
TEXT→BOOLEAN、VARCHAR→INTEGER等)。
更改資料型別時的常見錯誤
沒轉換資料就報錯。 如果資料不能自動轉成新型別,一定要用 USING 指定轉換方式。
ALTER TABLE employees
ALTER COLUMN birth_date TYPE DATE;
-- 錯誤:欄位 'birth_date' 有不合法的 DATE 型別值
操作會鎖住表格。 要注意,改資料型別時,表格會被鎖住不能寫入,直到操作完成。大表格尤其要小心,最好選流量低的時段操作。
跟其他表格和外鍵有關的問題。 如果欄位是外鍵的一部分,改型別會更麻煩。PostgreSQL 會要求你重建外鍵。
實用小撇步
一定要先檢查現有資料。 先用像 SELECT DISTINCT column_name 這種查詢,看看資料能不能順利轉型。
先測試再動手。 建個臨時表來練習,確定沒問題再改正式表。例如:
CREATE TEMP TABLE temp_students AS SELECT * FROM students;
別忘了 USING。 當型別差很大時(像 TEXT → NUMERIC),USING 就是你的救星。
現在你已經知道怎麼在 PostgreSQL 裡改欄位的資料型別啦。希望下次要調整資料結構時,你會很有信心。表格很聰明,但偶爾也要升級一下啦!
GO TO FULL VERSION