| 特性 | Primary Key (PK) | Unique Constraint (UK) |
|---|---|---|
| 每表數量 | 僅 1 個 | 可多個 |
| 空值允許 | 所有列 NOT NULL | 允許 NULL (單列唯一約束下多行 NULL 合法) |
| 默認索引 | 自動創建唯一索引 | 自動創建唯一索引 |
| 外鍵引用 | 可被 FK 引用 | 可被 FK 引用 (被引用列必須 PK 或 UK) |
| 複合鍵前綴性 | WHERE 條件需含首列才用索引 | 同左 |
ON DELETE CASCADE (級聯刪除) 或 ON DELETE SET NULL。DROP TABLE parent CASCADE CONSTRAINTS,子表 FK 自動移除,數據保留。
-- 1. 創建表
CREATE TABLE pk_increase_test (
id NUMBER(10) PRIMARY KEY,
name VARCHAR2(30)
);
-- 2. 創建序列
CREATE SEQUENCE pk_incre_sequence
MINVALUE 1
NOMAXVALUE
START WITH 1
INCREMENT BY 1
NOCYCLE
NOCACHE;
-- 3. 創建觸發器
CREATE OR REPLACE TRIGGER pk_trigger
BEFORE INSERT ON pk_increase_test
FOR EACH ROW
BEGIN
SELECT pk_incre_sequence.NEXTVAL INTO :NEW.id FROM dual;
END;
/
-- 4. 測試
INSERT INTO pk_increase_test (id) VALUES (NULL); -- 觸發器填充 1
INSERT INTO pk_increase_test (id) VALUES (NULL); -- 2
INSERT INTO pk_increase_test (id) VALUES (NULL); -- 3
SELECT * FROM pk_increase_test;
-- ID NAME
-- 1
-- 2
-- 3
注意:即使 INSERT 顯式傳入 VALUES (181),觸發器仍會覆蓋為序列值 (除非加 WHEN (NEW.id IS NULL) 判斷)。
應用層直接調用序列:
-- Java/JDBC
String sql = "INSERT INTO pk_increase_test (id, name) VALUES (pk_incre_sequence.NEXTVAL, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "Test");
ps.executeUpdate();
優勢:無觸發器開銷、事務邊界清晰。劣勢:需應用層統一規範、多應用接入易不一致。
CREATE TABLE pk_identity_test (
id NUMBER(10) GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(30)
);
WHEN (NEW.id IS NULL))。PK_表名、UK_表名_列名、FK_子表_父表、SEQ_表名、TRG_表名_BIR。