分表分庫架構下需全局唯一自增 ID。利用 InnoDB 行鎖 (SELECT ... FOR UPDATE) 或 LAST_INSERT_ID() 可實現無鎖高併發 ID 生成。本文提供兩種方案完整 SQL 與 PHP 調用範例。
CREATE TABLE auto_id (
idname VARCHAR(20) NOT NULL DEFAULT '',
id BIGINT(20) NOT NULL DEFAULT 0,
PRIMARY KEY (idname)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DELIMITER //
CREATE PROCEDURE get_increment_id(
IN idname_in VARCHAR(20), IN small_in BIGINT, OUT id_out BIGINT
)
BEGIN
DECLARE oldid BIGINT;
START TRANSACTION;
SELECT id INTO oldid FROM auto_id WHERE idname=idname_in FOR UPDATE;
IF oldid IS NULL THEN
INSERT INTO auto_id(idname,id) VALUES(idname_in, small_in);
SET id_out = small_in;
ELSE
UPDATE auto_id SET id=id+1 WHERE idname=idname_in;
SET id_out = oldid+1;
END IF;
COMMIT;
END//
DELIMITER ;
PHP 調用:CALL get_increment_id('key', 1000, @id); SELECT @id;
CREATE TABLE test_id (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;
-- 獲取下一 ID
UPDATE test_id SET id = LAST_INSERT_ID(id + 1);
SELECT LAST_INSERT_ID();
LAST_INSERT_ID() 為連接級變數,天然線程安全,但每種 ID 需一張表。