Oracle 無原生 AUTO_INCREMENT,傳統方案為 Sequence + BEFORE INSERT Trigger;12c 引入 IDENTITY 欄位原生支援自增。本文完整示範兩種模式的建立、使用、效能差異、遷移策略,並解析 Sequence 核心參數與快取機制。
CREATE TABLE example (
id NUMBER(10) NOT NULL PRIMARY KEY,
name VARCHAR2(25),
phone VARCHAR2(10),
address VARCHAR2(50)
);
CREATE SEQUENCE emp_sequence
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
CACHE 20; -- 關鍵:快取 20 個值於 SGA,大幅降低序號產生鎖競爭
CREATE OR REPLACE TRIGGER trg_example_auto_id
BEFORE INSERT ON example
FOR EACH ROW
WHEN (NEW.id IS NULL)
BEGIN
SELECT emp_sequence.NEXTVAL INTO :NEW.id FROM dual;
END;
/
INSERT INTO example (name, phone, address) VALUES ('Cao', '56498543', 'Hebei');
INSERT INTO example (name, phone, address) VALUES ('Liu', '13800001111', 'Beijing');
SELECT * FROM example;
CREATE TABLE example_new (
id NUMBER(10) GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR2(25),
phone VARCHAR2(10),
address VARCHAR2(50)
);
-- 或允許手動指定 ID(GENERATED BY DEFAULT)
CREATE TABLE example_flex (
id NUMBER(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
...
);
GENERATED ALWAYS:不可手動指定 ID,違例報錯。GENERATED BY DEFAULT:可手動指定,未指定時自動取序號。ISEQ$$_),可透過 USER_TAB_IDENTITY_COLS 查詢。| 參數 | 預設 | 建議生產值 | 影響 |
|---|---|---|---|
| INCREMENT BY | 1 | 1 | 步長 |
| START WITH | 1 | 1 或業務最大值+1 | 起始值 |
| MAXVALUE / NOMAXVALUE | NOMAXVALUE | NOMAXVALUE | 上限,達到後報錯或 CYCLE |
| CYCLE / NOCYCLE | NOCYCLE | NOCYCLE | 循環重用,主鍵嚴禁 |
| CACHE / NOCACHE | CACHE 20 | CACHE 100~1000 | 快取數量,越大效能越好,但實例崩潰會丟失快取值(不連續) |
| ORDER / NOORDER | NOORDER | NOORDER (RAC 必須 ORDER) | 保證跨節點全域有序,RAC 環境必開 |
| 維度 | Sequence + Trigger | IDENTITY (12c+) |
|---|---|---|
| 插入延遲 | Trigger 呼叫開銷 ~5-10% | 內核級實作,零開銷 |
| 平行插入擴展性 | 受 Trigger 序列化影響 | 原生支援,無瓶頸 |
| 序號連續性 | 同樣受 CACHE 影響 | 同樣受 CACHE 影響 |
| 相容性 | 所有版本 | 12.1+ |
| 遷移成本 | 既有系統改動大 | 新表直接用,舊表可重建 |
WHEN (NEW.id IS NULL) 必加。NOCACHE(效能大幅下降)。DBMS_METADATA 導出重建。-- 1. 重建表
CREATE TABLE example_new AS SELECT * FROM example WHERE 1=0;
ALTER TABLE example_new MODIFY (id GENERATED ALWAYS AS IDENTITY);
-- 2. 複製資料(ID 保留)
INSERT INTO example_new SELECT * FROM example;
-- 3. 切換
RENAME example TO example_old;
RENAME example_new TO example;
-- 重建索引、約束、授權、觸發器
選擇 Sequence+Trigger 還是 Identity,取決於版本、相容性、效能敏感度。新專案 12c+ 首選 Identity;既有系統若無效能痛點,維持現狀即可。核心原則:主鍵序號唯一、不連續可接受、CACHE 與 ORDER 根據架構正確配置。