首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 自增欄位實現全攻略:Sequence + Trigger 模式、IDENTITY 列 (12c+) 與效能優化建議

     編輯:Oracle 資料庫基礎

Oracle 無原生 Auto_Increment,但有更強大的機制

不同於 MySQL AUTO_INCREMENT、SQL Server IDENTITY、PostgreSQL SERIAL,Oracle 歷史上透過 **Sequence(序列)+ Trigger(觸發器)** 實現自增,12c 起引入標準 **IDENTITY 列**。兩種模式並存,各有優勢。

模式一:Sequence + Trigger(11g 及之前標準、12c+ 仍支援)

Step 1:建立 Sequence

CREATE SEQUENCE seq_test
    MINVALUE 1
    MAXVALUE 9999999999999999999999999999
    START WITH 1
    INCREMENT BY 1
    NOCACHE          -- 不緩存:避免實例重啟/故障導致間隙 (效能較差)
    -- CACHE 20      -- 生產建議:緩存 20-100,極大提升高併發效能
    NOORDER;         -- RAC 環境不保證全局有序 (單機可 ORDER)

CACHE 參數關鍵權衡:

  • NOCACHE:每次 NEXTVAL 寫入磁碟,**零間隙**,但高併發嚴重爭用 Sequence 緩存鎖
  • CACHE 100:記憶體預取 100 個值,**效能提升 10-100 倍**,但實例崩潰/重啟會丟失未用值 → **主鍵間隙** (業務通常可接受)

Step 2:建立 BEFORE INSERT Trigger

CREATE OR REPLACE TRIGGER trg_test_auto_id
BEFORE INSERT ON test
FOR EACH ROW
DECLARE
    v_next_id NUMBER;
BEGIN
    -- 僅當 ID 為 NULL 或 0 時自動賦值 (支援業務手動指定 ID)
    IF :NEW.id IS NULL OR :NEW.id = 0 THEN
        SELECT seq_test.NEXTVAL INTO v_next_id FROM DUAL;
        :NEW.id := v_next_id;
    END IF;
END;
/
SHOW ERRORS

:NEW 與 :OLD 關鍵字:

  • :NEW:INSERT/UPDATE 時的**新值**;INSERT 時原值為 NULL
  • :OLD:UPDATE/DELETE 時的**舊值**;DELETE 時新值為 NULL
  • Trigger 只能在 BEFORE 階段修改 :NEW,AFTER 已寫入不可改

Step 3:測試驗證

INSERT INTO test (name, location, value) VALUES ('A', 'Loc1', 10);
INSERT INTO test (name, location, value) VALUES ('B', 'Loc2', 20);
INSERT INTO test (id, name, location, value) VALUES (100, 'C', 'Loc3', 30); -- 手動指定 ID

SELECT * FROM test ORDER BY id;
-- 結果:
-- ID  NAME  LOCATION  VALUE
-- 1   A     Loc1      10
-- 2   B     Loc2      20
-- 100 C     Loc3      30  (手動指定,Sequence 繼續從 3 開始)

模式二:IDENTITY 列(12c+ 标準語法、效能最佳)

-- 12c+ 標準語法
CREATE TABLE test_modern (
    id          NUMBER GENERATED ALWAYS AS IDENTITY,  -- 或 GENERATED BY DEFAULT
    name        VARCHAR2(20),
    location    VARCHAR2(20),
    value       NUMBER
);

-- 進階選項
CREATE TABLE test_advanced (
    id          NUMBER GENERATED BY DEFAULT AS IDENTITY 
                (START WITH 1 INCREMENT BY 1 CACHE 20 NOORDER),
    name        VARCHAR2(20)
);

IDENTITY 關鍵字解析

關鍵字行為適用場景
GENERATED ALWAYS AS IDENTITY**強制自增**,INSERT 時不可指定 ID,指定會報錯純代理鍵、嚴格防範手動干擾
GENERATED BY DEFAULT AS IDENTITY**預設自增**,允許 INSERT 手動指定 ID (覆蓋自增)遷移舊資料、合併資料、測試需手動控制 ID
GENERATED BY DEFAULT ON NULL AS IDENTITY18c+ 新增:僅當值為 NULL 才自增 (等同 Trigger 邏輯)最靈活,兼容手動指定與自動賦值

兩模式深度對比

維度Sequence + TriggerIDENTITY 列 (12c+)
效能Trigger 開銷:每行額外 PL/SQL 呼叫、Context Switch**內核級實現**,零 PL/SQL 開銷,效能提升 30-50%
遷移相容性所有版本通用僅 12c+,跨版本遷移需改寫
靈活度可在 Trigger 實現複雜邏輯 (條件賦值、日誌、驗證)語法固定,複雜邏輯仍需 Trigger 輔助
工具支援所有工具識別現代工具 (SQLcl, SQL Developer, ORDS) 完美識別
間隙控制Sequence 參數完全控制內建 Sequence 參數同樣控制
DDL 管理兩個物件 (Sequence, Trigger) 獨立管理單一欄位定義,DROP TABLE 自動清理

效能優化:高併發插入的關鍵參數

1. Sequence CACHE 設定指南

併發級別建議 CACHE預估間隙風險備註
低 (< 10 TPS)NOCACHE 或 CACHE 10極低開發/測試環境
中 (10-1000 TPS)CACHE 100低 (重啟丟失 < 100)大多數生產 OLTP
高 (> 1000 TPS)CACHE 1000-10000中 (需監控)核心交易系統,配合 RAC ORDER

2. RAC 環境:ORDER vs NOORDER

-- 單機/非嚴格有序需求
CREATE SEQUENCE seq_ord NOORDER;  -- 預設,各實例獨立緩存,效能最佳

-- 業務要求全局嚴格遞增 (罕見)
CREATE SEQUENCE seq_ord ORDER;    -- 實例間協調,有效能代價

3. 批次插入優化:PL/SQL 批量綁定

-- 慢:逐行 INSERT 觸發 Trigger/Sequence
FOR i IN 1..10000 LOOP
    INSERT INTO test (name) VALUES ('Batch_'||i);
END LOOP;

-- 快:FORALL + 批量綁定 (繞過 Trigger 逐行開銷)
DECLARE
    TYPE name_arr IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
    l_names name_arr;
BEGIN
    FOR i IN 1..10000 LOOP l_names(i) := 'Batch_'||i; END LOOP;
    FORALL i IN 1..10000
        INSERT INTO test (name) VALUES (l_names(i));
END;
/
-- IDENTITY 列下 FORALL 直接由內核批量分配 Sequence 值,極快

遷移指南:舊系統 Trigger 模式 → IDENTITY 列

  1. 確認資料庫版本 ≥ 12.1
  2. 檢查現有 Trigger 邏輯:是否有除自增外的副作用(日誌、驗證、衍生欄位)
  3. 若無副作用:ALTER TABLE test MODIFY id GENERATED BY DEFAULT AS IDENTITY (12c+ 支援)
  4. 若有副作用:保留 Trigger 處理副作用,ID 改用 GENERATED BY DEFAULT ON NULL AS IDENTITY (18c+) 或維持原狀
  5. 刪除 Sequence (若無其他表共用) 與純自增 Trigger
  6. 全量回歸測試:插入、批次、手動指定 ID、匯入導出

總結

**12c 以前**:Sequence + Trigger 是唯一標準方案,**關鍵優化在於 Sequence CACHE 設定**。**12c 起**:**IDENTITY 列為首選**,效能優越、語法標準、工具友好。遷移時評估 Trigger 附加邏輯,**「能用 IDENTITY 就用 IDENTITY,複雜邏輯輔以 Trigger」**。無論哪種模式,**主鍵間隙是正常現象,業務層切勿依賴連續性**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved