首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 自動遞增主鍵實作:Sequence + Trigger 標準模式與 12c Identity Column 新寫法

     編輯:Oracle 資料庫相關知識

傳統兩步驟實作 (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;
/

命名慣例建議 (避免衝突)

物件命名格式範例
SequenceSEQ_<Schema>_<Table>_<Column>SEQ_HR_EMPLOYEES_EMPLOYEE_ID
TriggerTRG_<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

遷移建議

  1. 新專案直接使用 Identity Column
  2. 舊系統可保持 Sequence+Trigger,除非有效能瓶頸
  3. 若遷移:ALTER TABLE t MODIFY id GENERATED ALWAYS AS IDENTITY; (12c+)
  4. 遷移後可刪除對應觸發器與序列 (確認無其他處引用)

常見問題

問題說明
主鍵跳號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 = '...';
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved