傳統兩步驟實作 (11g 及之前通用)
步驟 1:建立序列
CREATE SEQUENCE sequence_identity
START WITH 1 -- 起始值
INCREMENT BY 1 -- 遞增值
MAXVALUE 9999999999 -- 最大值 (或 NOMAXVALUE)
NOCYCLE -- 不循環
NOCACHE; -- 不快取 (避免跳號,效能稍低)
-- CACHE 1000; -- 高併發建議快取
步驟 2:建立 BEFORE INSERT 行觸發器
CREATE OR REPLACE TRIGGER trigger_identity
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
SELECT sequence_identity.NEXTVAL
INTO :NEW.column_name
FROM DUAL;
END;
/
命名慣例建議 (避免衝突)
| 物件 | 命名格式 | 範例 |
| Sequence | SEQ_<Schema>_<Table>_<Column> | SEQ_HR_EMPLOYEES_EMPLOYEE_ID |
| Trigger | TRG_<Table>_BI_<Column> | TRG_EMPLOYEES_BI_EMPLOYEE_ID |
Oracle 12c+ 原生 Identity Column (推薦)
-- 永遠自動產生,不允許手動指定
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(100)
);
-- 允許手動指定值,NULL 時自動產生
CREATE TABLE t (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
name VARCHAR2(100)
);
-- 自訂序列參數
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY
(START WITH 100 INCREMENT BY 10 MAXVALUE 10000 CYCLE CACHE 100),
name VARCHAR2(100)
);
Identity Column 優勢
- 效能更好:無觸發器呼叫開銷,內部最佳化
- 語意清晰:DDL 直接表達意圖
- 支援所有序列選項:START WITH, INCREMENT BY, MAXVALUE, CYCLE, CACHE, ORDER/NOORDER
- 匯入/匯出更簡單:Data Pump 自動處理序列狀態
- 無觸發器失效風險:DDL 變更不會導致觸發器 INVALID
遷移建議
- 新專案直接使用 Identity Column
- 舊系統可保持 Sequence+Trigger,除非有效能瓶頸
- 若遷移:
ALTER TABLE t MODIFY id GENERATED ALWAYS AS IDENTITY; (12c+)
- 遷移後可刪除對應觸發器與序列 (確認無其他處引用)
常見問題
| 問題 | 說明 |
| 主鍵跳號 | Sequence 特性:Cache 失效、Rollback、實例重啟皆導致跳號。不可避免,業務勿依賴連續性。 |
| 手動插入指定主鍵 | Identity Column 預設不允許。需用 GENERATED BY DEFAULT ON NULL 或關閉觸發器手動處理。 |
| 合併資料庫主鍵衝突 | 使用 INCREMENT BY 設定不同步長 (如節點1增1, 節點2增2) 或設定不同 START WITH 範圍。 |
| 觸發器編譯失效 | DDL 變更參考表結構會導致觸發器 INVALID。需 ALTER TRIGGER ... COMPILE; 重新編譯。 |
效能調優建議
- 高併發 OLTP:
CACHE 1000 或更大,減少序列鎖競爭
- 批次載入:暫停觸發器,使用
sequence.NEXTVAL 直接賦值
- 監控序列狀態:
SELECT * FROM USER_SEQUENCES WHERE SEQUENCE_NAME = '...';