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

DB2 Sequence 實現自動主鍵生成:建立、調用與效能優化完整指南

     編輯:DB2 教學

DB2 Sequence(序列)是獨立於資料表的編號產生器,提供高效能、無鎖競爭的主鍵值生成機制,是替代 MAX(id)+1 模式的最佳選擇。本文涵蓋建立語法、調用方式、快取機制與實戰優化。

建立 Sequence 語法詳解


CREATE SEQUENCE schema.seq_name
  AS BIGINT                    -- 資料類型:SMALLINT/INTEGER/BIGINT/DECIMAL
  START WITH 1                 -- 起始值
  INCREMENT BY 1               -- 遞增值(負值為遞減)
  NO MAXVALUE                  -- 無上限(或指定 MAXVALUE 9999999999)
  NO MINVALUE                  -- 無下限
  CYCLE                        -- 達上限後循環(預設 NO CYCLE 報錯)
  CACHE 20                     -- 記憶體預先配置 20 個值(效能關鍵,預設 20)
  NO ORDER;                    -- 不保證跨分區全域有序(效能最佳)

關鍵參數效能影響

參數建議值說明
CACHE20 ~ 1000值越大越少同步 I/O,但資料庫異常關閉會遺失未使用的快取值(造成間隙)
CYCLE視業務主鍵通常 NO CYCLE;循環編號可用 CYCLE
ORDERNO ORDER分區環境下 NO ORDER 效能大幅優於 ORDER
資料類型BIGINT64 位元整數支援 9.2 兆次遞增,足應對極高併發

核心調用函數


-- 取得下一個值(最常用)
VALUES NEXT VALUE FOR schema.seq_name;
-- 或
SELECT NEXT VALUE FOR schema.seq_name FROM SYSIBM.SYSDUMMY1;

-- 取得當前會話最近使用的值
VALUES PREVIOUS VALUE FOR schema.seq_name;

-- 在 INSERT 中直接使用
INSERT INTO audit_log (log_id, msg) 
VALUES (NEXT VALUE FOR audit_seq, 'User login');

-- 批次插入自動生成連續主鍵
INSERT INTO audit_log (log_id, msg)
SELECT NEXT VALUE FOR audit_seq, 'Batch ' || CAST(ROW_NUMBER() OVER() AS VARCHAR(10))
FROM SYSCAT.TABLES FETCH FIRST 1000 ROWS ONLY;

進階應用模式

1. 多表共用單一 Sequence(全域唯一鍵)


CREATE SEQUENCE global_id_seq AS BIGINT START WITH 1 CACHE 100;

INSERT INTO orders (order_id, ...) VALUES (NEXT VALUE FOR global_id_seq, ...);
INSERT INTO shipments (ship_id, ...) VALUES (NEXT VALUE FOR global_id_seq, ...);
INSERT INTO invoices (inv_id, ...) VALUES (NEXT VALUE FOR global_id_seq, ...);

優點:跨表主鍵全域唯一,簡化合併查詢與資料整合。缺點:單點熱點,極高併發考慮分區 Sequence。

2. Identity Column vs Sequence 對比

特性IDENTITY COLUMNSEQUENCE
綁定對象單一資料表欄位獨立物件,多表共用
ALTER 靈活性受限(需重建表)隨時 ALTER SEQUENCE
跨分區有序ORDER 選項支援ORDER/NO ORDER 可選
效能表級鎖競爭獨立快取,無表鎖
遷移相容性標準 SQLDB2/Oracle/PostgreSQL 相容

建議:新系統優先使用 Sequence;既有 Identity Column 系統維持現狀。

3. 條件式序列生成(避免間隙)


-- 僅在成功插入時消耗序列值(需配合應用邏輯)
BEGIN ATOMIC
  DECLARE v_id BIGINT;
  SET v_id = NEXT VALUE FOR order_seq;
  INSERT INTO orders (order_id, ...) VALUES (v_id, ...);
  -- 失敗時序列值已消耗,間隙不可避免
END;

注意:Sequence 設計上不保證無間隙(快取遺失、Rollback、Crash 皆造成間隙),業務若要求連續編號需另行設計。

管理與監控


-- 查看序列定義
db2 "select * from syscat.sequences where seqschema='SCHEMA' and seqname='SEQ_NAME'"

-- 查看當前快取狀態(需 SYSADM)
db2 "select * from table(sysproc.snap_get_seq('SCHEMA', 'SEQ_NAME')) as t"

-- 修改快取大小
db2 "alter sequence schema.seq_name cache 100"

-- 重設序列(謹慎使用)
db2 "alter sequence schema.seq_name restart with 10000"

-- 刪除序列
db2 "drop sequence schema.seq_name"

效能優化檢查清單

  1. CACHE ≥ 100:高併發插入場景建議 500~1000
  2. NO ORDER:分區環境必須設定
  3. 避免單一熱點 Sequence:極高併發(>5000 TPS)考慮分區 Sequence 或應用層批次預取
  4. 監控 SYSIBM.SYSDUMMY1 爭用:大量 SELECT NEXT VALUE ... FROM SYSIBM.SYSDUMMY1 可能成為瓶頸,改用 VALUES NEXT VALUE ...
  5. 定期檢查間隙:SELECT MAX(id) - COUNT(*) FROM table 估算間隙率

常見錯誤與解決

錯誤原因解決
SQL0348N序列達 MAXVALUE 且 NO CYCLEALTER SEQUENCE 設定 CYCLE 或擴大 MAXVALUE
SQL0802N數值溢位(超出資料類型範圍)改用 BIGINT 或 DECIMAL(31,0)
SQL0723N觸發程序中使用 NEXT VALUE 違反限制移至應用層或 BEFORE INSERT 觸發程序外部調用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved