mysql_insert_id 或类似的东西返回最后一个 mysql UUID()

发布于 2024-10-12 09:23:06 字数 310 浏览 3 评论 0原文

如何返回最后生成的 UUID() (主键) - 有类似 mysql_insert_id 的东西吗?

uuidtable

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

与主键 uuid() 匹配的多个 id_u

插入:插入 uuidtable (uuid,id_u) 值 (uuid(),id)

其中 id 是数字,当然,uuid 被转义为

 uuid 

How do you return the last generated UUID() (primary key) - is there something like mysql_insert_id for that?

Table uuidtable:

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

multiple id_u matched with a primary key uuid()

insert: insert into uuidtable (uuid,id_u) values (uuid(),id)

where id is a number, of course, and uuid is escaped with

 uuid 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

妄断弥空 2024-10-19 09:23:06

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

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 字节 <代码>字符字段。如果您确实想使用 MySQL 的 UUID() 算法,请去掉连字符和 UNHEX(): 旁白

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

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

Write yourself a trigger like so:

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

Following an insert:

SELECT @last_uuid

MySQL's user-defined variables are connection-specific, so you don't have to worry about getting another connection's @last_uuid.

One point of concern: If you're using the uuid as a key, in order for it to be maximally performant, it should be stored as a 16-byte binary field and not a 36-byte char field. If you really want to use MySQL's UUID() algorithm, strip out the hyphens and UNHEX() it:

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

Aside: PostgreSQL actually has a UUID data type (but no built-in UUID() function), which just means you don't have to re-HEX() the field in order to avoid getting binary garbage in your terminal on SELECT.

禾厶谷欠 2024-10-19 09:23:06

我不确定这是否可以在 mysql 中完成。

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

I'm not sure it's even possible to do in mysql.

The only obvious solution I can get of is to generate UUID() in separate query and then insert the record with known id.

﹉夏雨初晴づ 2024-10-19 09:23:06

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 变量中。要读回它,只需像以前一样 SELECT @last_uuid 即可。

Richard 的答案使用 AFTER INSERT,这避免了 BEFORE INSERT 的问题,即使行插入失败也会设置 UUID 变量。我还没有测试过这个方法——虽然我觉得在正常情况下完全没问题,但我想知道集群复制是否会出现问题。

关于性能的说明:您会注意到我的 UUID 插入通过 REPLACE() 和 UNHEX() 将其存储为 16 字节二进制字段 - 这只是普通 INT 主键存储空间的 4 倍(并且仅为普通 INT 主键存储空间的两倍) a BIGINT),并且查询速度比基于字符串的 UUID 键快得多。

当查询和读取此类二进制值时,MySQL 函数 HEX()UNHEX() 将非常有用,以十六进制表示法(前面带有 <代码>0x)。

Following on from Richard's solution, you can actually use a trigger to get all the functionality you'd expect from a regular autoincrementing 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

This will allow you to perform inserts without manually inserting the UUID primary key, and automatically store the auto-generated ID into the @last_uuid variable. To read it back out, just SELECT @last_uuid as before.

Richard's answer uses AFTER INSERT, which avoids the issue with BEFORE INSERT where the UUID variable is set even when a row insert fails. I haven't tested this method - while I feel that it would be totally fine under normal circumstances I wonder whether there would be issues with cluster replication.

Notes on performance: You'll notice my UUID insertion runs through REPLACE() and UNHEX() to store it as a 16-byte binary field - this is only 4x the storage space of a normal INT primary key (and only twice that of a BIGINT), and will be much faster to query than string-based UUID keys.

When querying and reading such binary values, the MySQL functions HEX() and UNHEX() will be very helpful, as will writing your query values in hex notation (preceded by 0x).

随波逐流 2024-10-19 09:23:06

要获取/返回数据库生成的 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

我们在插入查询之前创建 uuid 并将其保存到“@uuid”。这允许我们使用它(对于其他表,作为外键)或返回它的值,例如在您的(php-)代码中使用它,重定向,调用或其他什么。

way1:插入查询后再次设置变量,具体取决于插入是否成功。如果插入失败,我们的查询返回为 null,因此我们可以在应用程序中进行处理,并且我们避免使用我们认为已使用但从未使用过的 uuid。

方式2:只需保存行/查询并让变量存在。我们的返回是干净的,但变量仍然在数据库的内存中。

这种方法的好处:我们可以将其触发到数据库一次并获得一个返回,如果我们首先运行一个 select 来获取 uuid 并随后插入,我们可能会通过 db-driver-network-connection 获得潜在的双重延迟。

To get/return a database-generated-uuid we can use a database-variable:

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

We create the uuid before the insert-query and saves it to '@uuid'. This allows us to use it (for other tables, as foreign key) or return its value, e.g. to use it in your (php-)code, to redirect, call or whatever.

way1: After the insert-query set the variable again, depending of the success of the insert. If the insert failed, our query return is null, so we can handle in our application, and we avoid to use uuid which we thought it was used, but never was.

way2: Just save rows/queries and let the variable existing. Our return is clean, but the variable is still in the memory of the database.

Benefit of this method: We can fire it to the database once and get one return, if we first run a select to get an uuid and insert after, we could get a potential double-delay by the db-driver-network-connection.

等数载,海棠开 2024-10-19 09:23:06

嗨,我发现的唯一可靠的方法是将 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 ;

我希望上述内容有意义..

Hi the only sure way I found is to store uuid in a variable. Then use the variable in the insert query as follows:

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 ;

I hope the above makes sense..

眼中杀气 2024-10-19 09:23:06

对于特定表,我想从无符号整数、自动递增 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(零),表面上使用表中的正确键正确完成更新

但是,如果我使用无符号整数:

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

一切都很好,新创建的 id 存储在 如果默认

值是 uuid_short() ,是否有其他方法可以找到最后创建的 PK ?

For a specific table I'd like to move from an unsigned integer, auto increment id to uuid_short() id.

The table looks like this

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;

The insert query is generated with a prepared statement setting and binding all the values.

If I do this the PDO::lastInsertID is always 0 (zero) where in face the update is done correctly with a proper key in the table

However, if I use an unsigned int:

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

all is well and the newly created id is stored in lastInsertId

Is there an alternative to find the last created PK if the default is uuid_short() ?

风筝在阴天搁浅。 2024-10-19 09:23:06

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

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

If you're using MariaDB, you don't have to create a trigger for each table.
Instead, you can easily retrieve the UUID by adding a RETURNING clause to your query:

INSERT INTO uuidtable (uuid, id_u) VALUES (UUID(), id) RETURNING uuid;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文