選資料型別就像選工具一樣。你總不會拿螺絲起子去敲釘子吧(希望啦)。資料庫也是一樣:選對資料型別會大大影響效能、省記憶體,還有管理資料的方便度。舉例來說,如果我們用 REAL 來存錢,精確度就會出問題;而用 TEXT 取代 VARCHAR 來存短字串,反而會讓資料庫佔更多記憶體。
選資料型別時要考慮幾個重點:
資料性質
先搞清楚資料屬於哪一類:數字、字串、布林值、日期,還是更複雜的東西,比如 JSON 結構。
資料量
你打算存多少資料?像是字串如果不超過 50 個字,選 VARCHAR(50) 比 TEXT 好。
精確度與範圍
你需不需要很高的精確度(像財務計算那樣)?要不要限制數值範圍?
查詢頻率與型態
你會多常查這些資料?要注意像 JSONB 這種複雜型別,處理起來會比較吃資源。
資料型別選擇範例
不同資料,不同需求。有的地方要精確到小數點,有的只要能塞進去就好。下面有幾個例子,教你怎麼針對情境選對資料型別。
財務資料
存錢這種事,跟會計一樣,不能出錯。所以最推薦用 NUMERIC,這樣精確度才夠。比如我們想要一個有這些欄位的表:
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| id | SERIAL | 主鍵 |
| amount | NUMERIC(10, 2) | 十位數,其中兩位是小數 |
| currency_code | CHAR(3) | ISO 貨幣代碼,例如 "USD", "EUR" |
| transaction_date | TIMESTAMP | 交易時間,預設是現在 |
為什麼不用 REAL?因為浮點數會有精確度問題,這對財務來說超級致命。
字串資料
如果你要存使用者名稱、地址或其他字串,能設定最大長度就盡量設定。像 VARCHAR(50) 比 TEXT 更好。這樣可以避免出錯,也比較省記憶體。
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| id | SERIAL | 主鍵 |
| username | VARCHAR(50) | 使用者登入名,唯一且必填 |
| VARCHAR(255) | 電子郵件 | |
| bio | TEXT | 個人簡介,允許很長的文字 |
如果字串長度固定(像國家兩碼代碼),就用 CHAR:
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| code | CHAR(2) | ISO 國家代碼(例如 "US"),主鍵 |
| name | VARCHAR(100) | 國家名稱,必填 |
時間戳記資料
要存事件時間或行程,通常用 TIMESTAMP,因為它同時有日期跟時間。
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| id | SERIAL | 主鍵 |
| event_name | VARCHAR(100) | 事件名稱 |
| start_time | TIMESTAMP | 事件開始時間,必填 |
| end_time | TIMESTAMP | 事件結束時間,必填 |
如果只要時間不用日期,就用 TIME;只要日期不用時間,就用 DATE。
唯一識別碼
如果你要產生全域唯一的識別碼,就用 UUID。像是產生交易唯一識別碼:
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| request_id | UUID | 請求唯一識別碼,預設用 gen_random_uuid() 產生 |
| endpoint | VARCHAR(255) | API 端點地址 |
| timestamp | TIMESTAMP | 請求時間,預設是現在 |
JSONB:複雜結構
如果你要存結構會變動或很複雜的資料,比如使用者設定或 metadata,就用 JSONB。
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| user_id | SERIAL | 主鍵(使用者 ID) |
| preferences | JSONB | 使用者設定(JSON 格式) |
用 JSONB 很方便,但要注意如果大量 insert/update,效能會掉。
陣列
如果你要存一堆同類型的資料,比如標籤列表,就用陣列:
| 欄位名稱 | 資料型別 | 說明 |
|---|---|---|
| id | SERIAL | 主鍵 |
| title | VARCHAR(255) | 文章標題 |
| tags | TEXT[] | 標籤陣列 |
依任務分類的資料型別總覽
| 任務型態 | 推薦資料型別 | 範例 |
|---|---|---|
| 資料記錄識別碼 | SERIAL, BIGSERIAL, UUID |
id SERIAL PRIMARY KEY |
| 數量、整數 | INTEGER, BIGINT |
quantity INTEGER |
| 財務計算 | NUMERIC |
price NUMERIC(10, 2) |
| 字串儲存 | VARCHAR(n), TEXT |
username VARCHAR(50) |
| 短固定字串 | CHAR(n) |
status CHAR(1) |
| 日期與時間 | DATE, TIME, TIMESTAMP |
created_at TIMESTAMP DEFAULT NOW() |
| 唯一識別碼 | UUID |
id UUID PRIMARY KEY DEFAULT gen_random_uuid() |
| 複雜結構(JSON) | JSONB |
metadata JSONB |
| 值列表 | ARRAY |
tags TEXT[] |
| 布林值 | BOOLEAN |
is_active BOOLEAN |
你大概除了 SERIAL 以外都認識了。其實 SERIAL 就是 INTEGER,專門拿來當表格裡的主鍵。
它會在你每次新增一筆資料時自動加 1。比如你加 10 筆,第一筆 id 是 1,第二筆是 2,以此類推。這些細節我們下堂課會再聊更多 :)
GO TO FULL VERSION