今天我們要仔細聊聊資料庫操作裡一個很重要的點——怎麼在有 NOT NULL 跟 DEFAULT 約束的資料表裡插入資料。你現在應該已經會用 INSERT INTO 的基本語法,也知道怎麼往有特定結構的資料表加資料。現在是時候深入一點了——因為處理這些約束常常讓開發者頭很痛。不過別擔心,這堂課結束你就能很順地搞定這些機制啦!
什麼是約束?
約束就是加在資料表欄位上的規則。它們幫你確保資料是合邏輯的。比如說,有些欄位不能留空(NOT NULL),或者你可以不填某個欄位,因為它有預設值(DEFAULT)。
約束的種類: - NOT NULL — 表示這個欄位不能是 NULL。 - DEFAULT — 設定如果沒填這個欄位時,自動用這個值。
約束可以幫你維護資料完整性。想像一下,你有個 students 的資料表,規定每個學生一定要有名字(NOT NULL)。如果沒有這個約束,有人忘記填名字,資料庫裡就會出現「沒名字的學生」。再舉個例子:你決定新課程的學分預設是 0(DEFAULT),這樣每次不用自己填。
怎麼用 NOT NULL 約束
NOT NULL 這個約束會強制你在新增資料時一定要填這個欄位。如果你想塞 NULL 或根本沒填,資料庫就會「生氣」(出錯)。來看個例子。
我們先建立一個簡單的 students 資料表:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL, -- 名字不能是空的
age INT
);
注意:name 欄位有 NOT NULL 約束,age 就沒有。
插入有 NOT NULL 約束的資料範例
現在來加幾個學生:
-- 成功插入的例子
INSERT INTO students (name, age) VALUES ('Alice', 23);
-- 成功:有填名字,符合 NOT NULL 約束
-- 出錯的例子:
INSERT INTO students (age) VALUES (30);
-- 錯誤:name 欄位不能是 NULL,因為有 NOT NULL 約束
如果你看到像 null value in column "name" violates not-null constraint 這種錯誤,不用怕——這只是 PostgreSQL 提醒你要小心點。
怎麼用預設值(DEFAULT)
DEFAULT 約束就是跟資料庫說:「如果有人忘記填這個欄位,就用這個預設值吧」。這樣開發者就不用每次都手動填。
有 DEFAULT 約束的資料表範例
我們來建立一個 courses 資料表:
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INT DEFAULT 0 -- credits 欄位的預設值是 0
);
插入有 DEFAULT 約束的資料範例
現在來加幾個課程:
-- 有明確填 credits
INSERT INTO courses (name, credits) VALUES ('Mathematics', 5);
-- 沒填 credits,會用預設值(0)
INSERT INTO courses (name) VALUES ('History');
-- 來看看結果
SELECT * FROM courses;
結果:
| id | name | credits |
|---|---|---|
| 1 | Mathematics | 5 |
| 2 | History | 0 |
注意:加 History 這門課時沒填學分,PostgreSQL 自動幫你把 credits 欄位設成 0。
同時用 NOT NULL 跟 DEFAULT 約束
這種欄位就算你沒填值也一定會有值。像 courses 資料表的 credits 欄位就可以同時有 DEFAULT 跟 NOT NULL,這樣就能保證沒人會不小心留空 NULL。
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INT NOT NULL DEFAULT 0
);
插入資料範例
假設每個新課程預設學分是 0,但不能是 NULL。
-- 成功:credits 用預設值
INSERT INTO courses (name) VALUES ('Physics');
-- 錯誤:credits 明確塞 NULL,但有 NOT NULL 約束
INSERT INTO courses (name, credits) VALUES ('Chemistry', NULL);
範例:加一個一定要有名字的學生
我們來建立一個有約束的 students 資料表:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL, -- 名字一定要填
enrollment_date DATE DEFAULT CURRENT_DATE -- 入學日期預設是今天
);
現在來加學生:
-- 有填名字,入學日期自動填
INSERT INTO students (name) VALUES ('Bob');
-- 試著不填名字(會出錯)
INSERT INTO students (enrollment_date) VALUES ('2024-10-01');
這就是 PostgreSQL 幫你確保資料正確的好例子:每個學生一定有名字,入學日期不用自己填。
小技巧跟「地雷」
你在用 NOT NULL 跟 DEFAULT 這些約束時,有幾個重點要記得。比如說,如果你的資料常常會有 NULL,那 NOT NULL 可能會讓你很頭大。還有,如果每個欄位都設預設值,有時候會不小心塞進不正確的資料(像是 0 取代真實值)。
通常你在現有資料表加新欄位時,舊資料的這個欄位會是 NULL。但如果你有設 DEFAULT X,整個欄位就會自動填 X。這超方便,也能幫你維護資料庫完整性。
舉例來說,新欄位是指向另一個資料表的 FOREIGN KEY。它不能是 NULL 或 0,一定要連到已經存在的資料。
如果忘記加約束怎麼辦?
別擔心——你隨時可以用 ALTER TABLE 指令補上約束。像這樣:
-- 幫現有欄位加 DEFAULT 約束
ALTER TABLE courses ALTER COLUMN credits SET DEFAULT 0;
-- 幫現有欄位加 NOT NULL 約束
ALTER TABLE students ALTER COLUMN name SET NOT NULL;
這些指令不會破壞你現有的資料——你可以很放心地在已經有資料的表上用。
現在你已經準備好用 PostgreSQL 的威力來管理約束啦!你的資料會更有結構、更不容易出錯,查詢也會更有邏輯、更好預測。
GO TO FULL VERSION