我的逻辑需要在INSERT之前知道表的ID(在插入时手动设置id)。因为使用这个ID的逻辑在多个服务器上,让mysql创建一个id可能是一个好主意,但我写的函数不是原子的,所以在高负载下调用它会返回一些同意的,而不是唯一的数字:
CREATE FUNCTION `generate_document_log_id`() RETURNS BIGINT(16)
BEGIN
DECLARE R_ID BIGINT(16);
UPDATE document_log_sequence SET id = id + 1;
SELECT id INTO R_ID FROM document_log_sequence;
RETURN R_ID;
END
我正在使用带有一列“id”的表“document_log_sequence”来存储最后一个ID,并为每个新ID增加它。 也许解决方案远非如此,但我没有更多的想法。
我忘了解释: 只有一个数据库服务器和n个客户端。上面的函数不是(种类)线程安全的。
答案 0 :(得分:1)
仅供参考,如果您只有一个数据库服务器,这将为您提供要插入的下一个ID的值:
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_NAME = 'my_table'
AND TABLE_SCHEMA = 'my_schema';
(编辑 - 我误解了这个问题)
答案 1 :(得分:1)
您可以使用 interleaved ID
的策略每个服务器的编号为0到n,并将其服务器编号添加到以n为单位的序列中。一个实现是使用AUTO_INCREMENT
表生成id,然后在这样的函数中使用该ID:
CREATE TABLE ID_CREATOR (ID INT AUTO_INCREMENT PRIMARY KEY);
假设有3台服务器且该服务器是服务器编号1,则此功能将为每台服务器提供唯一值:
CREATE FUNCTION generate_document_log_id() RETURNS INT
BEGIN
DECLARE NUMBER_OF_SERVERS INT DEFAULT 3; -- Or read from some table
DECLARE THIS_SERVER_ID INT DEFAULT 1; -- Or read from some table. Must be less than NUMBER_OF_SERVERS
INSERT INTO ID_CREATOR VALUES (); -- This creates the next id
RETURN LAST_INSERT_ID() * NUMBER_OF_SERVERS + THIS_SERVER_ID; -- Unique numbers that interleave each other
END
答案 2 :(得分:0)
有一些选项
1)您可以使用一个UUID,一个16字节(128位)的密钥;这个策略也适用于n个服务器数据库:
选择uuid(); (当然..你需要一个字段CHAR(32)来存储你的UUID在纯文本; MySQL没有字段os类型GUIID(128位)一段时间)
我穿着使用存储功能,这是我的一个版本:
BEGIN
DECLARE str_uuid varchar(32);
DECLARE cur1 CURSOR FOR select replace (o.oid, '-', '') from (select lower(UUID()) as oid) as o;
open cur1;
fetch cur1 into str_uuid;
close cur1;
return str_uuid;
END
2)您可以使用INT或BIGINT,但此策略仅适用于同一个数据库服务器:
考虑一个包含字段my_last_id,dt_hr_id(my_last_id是AUTOINCREMENT)的表 启动一个独立的连接,所以
关闭您的隔离连接;
这可以在存储过程/存储函数中执行,但您需要知道MySQL不支持同一连接中的多个事务,因此您需要在隔离连接中执行此操作。