因爲業務要求,需要在MySQL數據庫中,獲取下一個自增主鍵的值。
原先採用的方法是:
select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '數據庫名稱' AND TABLE_NAME = '表名稱' limit 1
但是這樣寫的話,在8.0以後的版本是取不到值的,必須在每一次需要獲取自增序列之前,多執行一條表分析的語句。然後語句就會變成下面這樣:
ANALYZE TABLE 表名;
select auto_increment FROM information_schema.tables
WHERE TABLE_SCHEMA = '庫名' AND TABLE_NAME = '表名' limit 1;
這樣寫會造成一個問題,當表中的數據較多的時候,會造成查詢的速度變慢。
因此,就要使用另外一個策略,就是自己創建一個自增序列。
這裏參考了 mysql 中創建自增的序列(Sequence)
由於mysql和oracle不太一樣,不支持直接的sequence,所以需要創建一張table來模擬sequence的功能。
1.創建sequence表
CREATE TABLE `sequence` (
`name` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '序列的名字',
`current_value` int(11) NOT NULL COMMENT '序列的當前值',
`increment` int(11) NOT NULL DEFAULT '1' COMMENT '序列的自增值',
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
2.創建–取當前值的函數
DROP FUNCTION IF EXISTS currval;
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM sequence
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER ;
3.創建–取下一個值的函數
DROP FUNCTION IF EXISTS nextval;
DELIMITER $
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
4.創建–更新當前值的函數
DROP FUNCTION IF EXISTS setval;
DELIMITER $
CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = value
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
5.使用及測試
INSERT INTO sequence VALUES ('testSeq', 0, 1);--添加一個sequence名稱和初始值,以及自增幅度
SELECT SETVAL('testSeq', 10);--設置指定sequence的初始值
SELECT CURRVAL('testSeq');--查詢指定sequence的當前值
SELECT NEXTVAL('testSeq');--查詢指定sequence的下一個值
這裏,testSeq可以認爲是一個表名,我們可以通過insert語句插入指定表的第一個序列,然後使用NEXTVAL方法,不斷更新這一列數據,來獲取下一個序列的值。可以通過這張表,來實現N張表的自增序列的統一管理。