mysql_insert_id或类似的代码来返回上一个mysql UUID()

7hiiyaii  于 2022-12-03  发布在  Mysql
关注(0)|答案(7)|浏览(153)

如何返回最后生成的UUID()(主键)--有没有类似mysql_insert_id这样的东西?
表格uuidtable

primary key: uuid uuid()
id_u (index): integer

多个id_u与主键uuid()匹配
插入:insert into uuidtable (uuid,id_u) values (uuid(),id)
其中id是一个数字,uuid用

uuid
k2arahey

k2arahey1#

为自己编写一个触发器,如下所示:

CREATE TRIGGER ai_uuidtable
AFTER INSERT ON uuidtable
FOR EACH ROW
SET @last_uuid = NEW.uuid;

插入后:

SELECT @last_uuid

MySQL的用户定义变量是特定于连接的,因此您不必担心获取另一个连接的@last_uuid
值得关注的一点是:如果你使用uuid作为一个键,为了使它的性能最大化,它应该被存储为一个16字节的binary字段,而不是一个36字节的char字段。如果你真的想使用MySQL的UUID()算法,去掉连字符和UNHEX()

UNHEX( REPLACE( UUID(), '-', '' ) )

旁白:PostgreSQL实际上有一个UUID数据类型(但没有内置的UUID()函数),这只是意味着您不必重新-HEX()字段,以避免在SELECT上的终端中获得二进制垃圾。

yizd12fk

yizd12fk2#

我不确定这是否可能在mysql中实现。
我能得到的唯一明显的解决方案是在单独的查询中生成UUID(),然后插入具有已知id的记录。

inkz8wg9

inkz8wg93#

要获取/返回数据库生成的uuid,我们可以使用数据库变量:

SET @uuid=UUID();
INSERT INTO uuidtable (uuid,id_u) values (@uuid,$number);
SET @uuid = IF(ROW_COUNT(),@uuid,null);#way1
SELECT @uuid;#way1
#SELECT IF(ROW_COUNT(),@uuid,null) as uuid;#way2

我们在insert-query之前创建uuid并将其保存到'@ uuid'中,这允许我们使用它(对于其他表,作为外键)或返回它的值,例如在您的(php-)代码中使用它,进行重定向,调用或其他操作。
way 1:在insert-query之后,根据插入是否成功,再次设置变量。如果插入失败,我们的查询返回空值,所以我们可以在应用程序中处理,并且我们避免使用uuid,我们认为它被使用过,但从来没有。
方法2:只保存行/查询并保留变量。我们的返回是干净的,但变量仍然在数据库的内存中。
该方法的优点:我们可以将其发送到数据库一次并获得一个返回值,如果我们首先运行select以获得uuid并在后面插入,我们可能会通过db-driver-network-connection获得潜在的双延迟。

0yycz8jy

0yycz8jy4#

根据Richard的解决方案,您实际上可以使用触发器来获得常规自动递增ID的所有功能:

CREATE TRIGGER `tablename_newid` 
BEFORE INSERT ON `tablename` 
FOR EACH ROW 
BEGIN 
    SET NEW.table_id = UNHEX(REPLACE(UUID(),'-',''));
    SET @last_uuid = NEW.table_id; 
END

这将允许您执行插入操作,而无需手动插入UUID主键,并自动将自动生成的ID存储到@last_uuid变量中。
Richard的答案是使用AFTER INSERT,它避免了BEFORE INSERT的问题,即使行插入失败,UUID变量也会被设置。我还没有测试过这种方法--虽然我觉得在正常情况下完全可以,但我想知道集群复制是否会有问题。
性能说明:您会注意到,我的UUID插入通过REPLACE()和UNHEX()将其存储为一个16字节的二进制字段--这仅是普通INT主键的4倍存储空间(仅是BIGINT主键的两倍),而且查询速度要比基于字符串的UUID键快 * 多 *。
当查询和阅读这样的二进制值时,MySQL函数HEX()UNHEX()将非常有帮助,以十六进制表示法(前面加上0x)编写查询值也是如此。

z3yyvxxp

z3yyvxxp5#

Hi我发现的唯一可靠的方法是将uuid存储在一个变量中。然后在插入查询中使用该变量,如下所示:

DELIMITER \\
CREATE PROCEDURE AddUserLinkRole(uname VARCHAR(50), passwd VARCHAR (40), role VARCHAR(50))
    BEGIN
        DECLARE UserUuid VARCHAR(36);
        DECLARE UserRole VARCHAR(50);
        /*Now initiate UserUuid = uuid() value*/
        SET UserUuid = uuid();
        SELECT RoleID INTO UserRoleID FROM Roles WHERE Description = role;
        /*Because I initiated UserUuid = uuid(), I can now refer to it anytime I wish using my UserUuid variable*/
        INSERT INTO Users(UserID,UserName,Password,RoleID) VALUES (UserUuid,uname,MD5(passwd),UserRoleID);
    END \\
DELIMITER ;

我希望以上是有意义的..

aor9mmx1

aor9mmx16#

对于一个特定的表,我想从一个无符号整数移动,自动递增id到uuid_short()id。
该表如下所示

CREATE TABLE IF NOT EXISTS `person` (
  `person_id` bigint(20) NOT NULL DEFAULT uuid_short(),
  `name` varchar(128) NOT NULL,
  `vorname` varchar(128) NOT NULL,
  `gender` char(1) NOT NULL DEFAULT 'u',
  PRIMARY KEY (`person_id`),
  KEY `gender` (`gender`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入查询是使用预准备语句设置和绑定所有值生成的。
如果我这样做,PDO::lastInsertID始终为0(零),而实际上,更新是使用表中的适当键正确完成的
但是,如果我使用无符号int:

`person_id` int(20) UNSIGNED NOT NULL AUTO_INCREMENT,

一切正常,新创建的id存储在lastInsertId中
如果默认值为uuid_short(),是否有替代方法来查找最后创建的PK?

iezvtpos

iezvtpos7#

如果使用MariaDB,则不必为每个表创建触发器。
相反,您可以通过向查询中添加RETURNING子句来轻松检索UUID:

INSERT INTO uuidtable (uuid, id_u) VALUES (UUID(), id) RETURNING uuid;

相关问题