本文以建表 → 建 Sequence → 建 Trigger → 測試插入的完整流程,詳細講解 Oracle 傳統自增主鍵實現,並補充 12c+ Identity Column 新語法、Sequence 進階參數與效能優化建議。
CREATE TABLE example (
id NUMBER(4) NOT NULL PRIMARY KEY,
name VARCHAR2(25),
phone VARCHAR2(10),
address VARCHAR2(50)
);
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 -- 每次遞增 1
START WITH 1 -- 從 1 開始
NOMAXVALUE -- 無上限
NOCYCLE -- 不循環
NOCACHE; -- 不緩存(無間隙需求時用 CACHE 20+)
參數權衡:
CACHE 20:SGA 預分配 20 個值,效能提升明顯,但 Crash 會丟失未用值產生間隙。NOCACHE:每次從磁碟讀取,無間隙,高併發下序列鎖成為瓶頸。ORDER:RAC 環境強制全域有序,需跨實例協調,效能大幅下降,非嚴格業務需求勿用。CREATE OR REPLACE TRIGGER trg_example_pk
BEFORE INSERT ON example
FOR EACH ROW
WHEN (NEW.id IS NULL) -- 僅在未提供 ID 時自動賦值
BEGIN
SELECT emp_sequence.NEXTVAL INTO :NEW.id FROM dual;
END;
/
INSERT INTO example (name, phone, address) VALUES ('Cao', '56498543', 'Heibei');
INSERT INTO example (name, phone, address) VALUES ('Li', '13800138000', 'Beijing');
SELECT * FROM example;
ID NAME PHONE ADDRESS
-- ---- ---------- -------
1 Cao 56498543 Heibei
2 Li 13800138000 Beijing
| 操作 | 語法 | 說明 |
|---|---|---|
| 取得下一值 | seq.NEXTVAL | 遞增並返回新值 |
| 取得當前值 | seq.CURRVAL | 返回當前 Session 最後取得的值,需先用過 NEXTVAL |
| 修改參數 | ALTER SEQUENCE seq INCREMENT BY 10 MAXVALUE 10000 CYCLE NOCACHE; | 不可修改 START WITH,需重建 |
| 刪除序列 | DROP SEQUENCE seq; |
-- 永遠自動產生,不允許手工指定
CREATE TABLE t1 (
id NUMBER GENERATED ALWAYS AS IDENTITY,
col VARCHAR2(10)
);
-- 允許手工覆蓋(DEFAULT ON NULL 同義)
CREATE TABLE t2 (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
col VARCHAR2(10)
);
-- 遷移既有 Sequence+Trigger 表
ALTER TABLE example MODIFY id GENERATED ALWAYS AS IDENTITY;
DROP TRIGGER trg_example_pk;
DROP SEQUENCE emp_sequence;
優勢:DDL 可見、無 Trigger 開銷、支援 ALTER TABLE ... MODIFY 參數調整、Data Pump 導出導入自動保留屬性。
CACHE 1000 + NOORDER + Identity Column。NOORDER 是預設且推薦,ORDER 僅用於極少數法規強制要求的場景。Sequence 產生的值只保證唯一、遞增,不保證連續。間隙是分散式系統的常態,業務邏輯切勿依賴連續性。