從 MySQL 轉戰 Oracle 的開發者最容易踩的坑,莫過於「自增主鍵」的缺失。MySQL 的 AUTO_INCREMENT 用慣了,到了 Oracle 卻發現原生不支援——直到 12c 版本推出 IDENTITY 特性才徹底改寫這段歷史。本文詳細對比兩大版本的實作方案,助您因地制宜選擇最佳策略。
12c 引入 ANSI SQL 標準的 GENERATED AS IDENTITY 語法,語法簡潔、效能優異、無需額外物件維護。
CREATE TABLE t (
id NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1),
name VARCHAR2(20),
password VARCHAR2(20),
CONSTRAINT pk_t PRIMARY KEY (id)
);
關鍵字解析:
GENERATED BY DEFAULT:允許手動指定值,若為 NULL 則自動取序列值GENERATED ALWAYS:強制由資料庫產生,手動插入會報錯START WITH 1 INCREMENT BY 1:起始值與遞增步長,支援負數與大數值若受限於 11g 環境,需手動建立序列與觸發器模擬自增行為。
CREATE TABLE t (
id NUMBER,
name VARCHAR2(20),
password VARCHAR2(20),
CONSTRAINT pk_t PRIMARY KEY (id)
);
CREATE SEQUENCE seq_t
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
NOCACHE;
參數說明: NOCACHE 確保序列值連續不跳號(犧牲少量效能),NOMAXVALUE 移除上限限制。
CREATE OR REPLACE TRIGGER tri_t
BEFORE INSERT ON t
FOR EACH ROW
WHEN (NEW.id IS NULL)
BEGIN
SELECT seq_t.NEXTVAL INTO :NEW.id FROM dual;
END;
/
注意事項:
id IS NULL 時觸發,保留手動指定主鍵的彈性:NEW.id 參照新資料列的欄位值dual 查詢 NEXTVAL,直接賦值會報錯| 維度 | Identity Column (12c+) | Sequence + Trigger (11g) |
|---|---|---|
| 語法複雜度 | 單一 DDL 完成 | 需建立 3 個物件 |
| 執行效能 | 內核層級優化,無上下文切換 | 觸發器引發 Context Switch,微量開銷 |
| 遷移相容性 | 僅 12c 以上支援 | 全版本相容 |
| 序列值管理 | 內建於欄位中 | 獨立物件,可跨表共用 |
| 備份/匯出 | 隨表結構自動處理 | 需額外匯出 Sequence 與 Trigger |
-- 指定緩存大小提升高併發效能
GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1 CACHE 100)
-- 強制自動產生,禁止手動插值
GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1)
-- 循環使用(慎用!主鍵衝突風險)
GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1 MAXVALUE 9999 CYCLE)
CACHE(如 20~100),大幅降低序列鎖競爭