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

Oracle 自增欄位實現方案深度解析:Trigger vs Sequence 效能對比

     編輯:Oracle 資料庫相關知識

前言

Oracle 資料庫並未像 SQL Server 那樣內建 IDENTITY 或 AUTO_INCREMENT 等自增欄位屬性。若要在 Oracle 中實現主鍵自動遞增,主流做法有兩種:觸發器 + 序列 組合,或直接使用 Sequence(序列)。本文將詳細比較這兩種方案的實作細節與效能差異。

方案一:Trigger(觸發器)+ 查詢 MAX(ID)

此作法在每次 INSERT 前,透過觸發器查詢表中現有的最大 ID 值,再加 1 指派給新行。雖然邏輯直觀,但存在嚴重效能隱憂。

程式碼範例

CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON your_schema.tablename
FOR EACH ROW
DECLARE
    v_max_id NUMBER;
    CURSOR cur_max IS SELECT MAX(id) FROM your_schema.tablename;
BEGIN
    OPEN cur_max;
    FETCH cur_max INTO v_max_id;
    CLOSE cur_max;

    IF v_max_id IS NULL THEN
        :new.id := 0;  -- 依業務需求設定初始值
    ELSE
        :new.id := v_max_id + 1;  -- 以 1 遞增
    END IF;
END;
/

關鍵點說明:

  • your_schema:資料庫使用者(SID)
  • tablename:目標資料表名稱
  • id:自增欄位名稱

效能缺陷分析

每次插入都需執行 SELECT MAX(id),隨著資料量增長,全表掃描成本線性上升。高併發場景下更會引發鎖競爭與「失聯更新」風險,極不推薦用於生產環境。

方案二:Sequence(序列)— 官方推薦標準做法

Oracle 內建 SEQUENCE 物件專為產生唯一、有序數值設計,具備記憶體快取、無鎖高併發等優勢。

建立序列語法

CREATE SEQUENCE your_schema.sequence_name
    INCREMENT BY 1      -- 每次遞增 1(預設值)
    START WITH 1        -- 起始值
    NOMAXVALUE          -- 不設上限
    MINVALUE 1          -- 最小值
    CACHE 20            -- 記憶體預先快取 20 個值,減少 I/O
    ORDER;              -- 確保 RAC 環境下全域有序

使用方式

-- 插入時直接引用
INSERT INTO your_schema.tablename (id, col1, col2)
VALUES (your_schema.sequence_name.NEXTVAL, 'value1', 'value2');

核心差異總結表

比較維度 Trigger + MAX(ID) Sequence
效能 差(全表掃描、鎖競爭) 優(記憶體快取、無鎖)
併發支援 弱(易發生重複鍵錯誤) 強(原子性保證)
維護複雜度 高(需管理觸發器、游標) 低(單一物件)
功能豐富度 僅支援簡單遞增 支援循環、快取、排序等進階選項
官方建議 不推薦 標準最佳實踐

進階提示:Oracle 12c+ Identity Column

自 Oracle 12c 起,原生支援 GENERATED AS IDENTITY 語法,底層自動建立序列,語法更簡潔:

CREATE TABLE t (
    id NUMBER GENERATED ALWAYS AS IDENTITY,
    name VARCHAR2(100)
);

這是現代 Oracle 開發的首選方案,兼具可讀性與效能。

結語

在 Oracle 實現自增主鍵,**Sequence 為唯一正統選擇**。Trigger 方案僅供教學參考,切勿用於實務專案。升級至 12c 以上版本時,請優先採用 Identity Column 簡化開發。

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