| 特性 | MySQL AUTO_INCREMENT | Oracle Sequence |
| 作用範圍 | 單表單列 | 跨表、跨列、多序列共存 |
| 步長控制 | 固定 1 | 可自定義 INCREMENT BY |
| 起始值 | 可設定 | 可設定 START WITH |
| 循環/緩存 | 不支持 | 支持 CYCLE / CACHE |
自建序列方案架構
- 序列表:存儲序列名、當前值、步長;
- 函數:
currval() 取當前值,nextval() 取下一值並自增;
- 觸發器:INSERT 前自動賦值實現透明自增。
完整實現腳本
1. 創建序列表
DROP TABLE IF EXISTS tb_sequence;
CREATE TABLE tb_sequence (
seq_name VARCHAR(50) NOT NULL COMMENT '序列名稱',
current_val INT NOT NULL COMMENT '當前值',
increment_val INT NOT NULL DEFAULT 1 COMMENT '步長',
PRIMARY KEY (seq_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 初始化序列
INSERT INTO tb_sequence VALUES ('seq_test1_num1', 0, 1);
INSERT INTO tb_sequence VALUES ('seq_test1_num2', 0, 2);
3. 當前值函數
CREATE FUNCTION currval(v_seq_name VARCHAR(50)) RETURNS INT
BEGIN
DECLARE value INT DEFAULT 0;
SELECT current_val INTO value FROM tb_sequence WHERE seq_name = v_seq_name;
RETURN value;
END;
4. 下一值函數
CREATE FUNCTION nextval(v_seq_name VARCHAR(50)) RETURNS INT
BEGIN
UPDATE tb_sequence SET current_val = current_val + increment_val WHERE seq_name = v_seq_name;
RETURN currval(v_seq_name);
END;
5. 測試函數
SELECT currval('seq_test1_num1'); -- 0
SELECT nextval('seq_test1_num1'); -- 1
SELECT nextval('seq_test1_num1'); -- 2
SELECT nextval('seq_test1_num2'); -- 2 (步長 2)
6. 業務表與觸發器
DROP TABLE IF EXISTS test1;
CREATE TABLE test1 (
name VARCHAR(255) NOT NULL,
value DOUBLE(255,0) DEFAULT NULL,
num1 INT(11) DEFAULT NULL,
num2 INT(11) DEFAULT NULL,
PRIMARY KEY (name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TRIGGER TRI_test1_num1 BEFORE INSERT ON test1
FOR EACH ROW
BEGIN
SET NEW.num1 = nextval('seq_test1_num1');
SET NEW.num2 = nextval('seq_test1_num2');
END;
7. 驗證效果
INSERT INTO test1 (name, value) VALUES ('1', 111), ('2', 222), ('3', 333), ('4', 444);
SELECT * FROM test1;
/*
name | value | num1 | num2
-----|-------|------|-----
1 | 111 | 1 | 2
2 | 222 | 2 | 4
3 | 333 | 3 | 6
4 | 444 | 4 | 8
*/
進階擴展建議
- 高併發優化:序列表單行更新易成為熱點,可採用「批次預取」模式:
nextval_batch(seq_name, batch_size) 一次更新 +N,應用端緩存分配;
- 持久化保證:InnoDB 事務保證序列不丟失,重啟後從 current_val 繼續;
- 監控告警:監控
current_val 接近 INT_MAX 時預警;
- 兼容性封裝:封裝為
SequenceDAO,業務代碼無感遷移。
MySQL 8.0+ 原生替代方案
MySQL 8.0 引入 SEQUENCE 對象(實為模擬),語法:
CREATE SEQUENCE seq_test START WITH 1 INCREMENT BY 1;
SELECT NEXT VALUE FOR seq_test;
但功能仍受限(不支持 CYCLE、CACHE 等),自建方案在靈活性上仍佔優。
- 上一篇文章: MySQL 多表連接查詢完全指南:內連接、外連接、自然連接與多表關聯實戰
- 下一篇文章: MySQL 運維實戰:死鎖、連接數、密碼、登錄、DATETIME .0、表空間 6 大高頻問題解決方案
Copyright ©
程式碼之家 All Rights Reserved