我在数据库中有一个存储项目的表。每个项目都有一个唯一的ID,DB在插入时生成(自动增量)
用户可以执行将X项添加到数据库的特定任务,但是我的程序(使用MySQL连接器的C ++服务器应用程序)应该立即返回数据库生成的ID。例如,如果我添加6个项目,则服务器必须向客户端返回6个新的唯一ID
做这种事最快/最干净的方法是什么?到目前为止,我一直在INSERT
后面跟着SELECT
每个新项目或INSERT
后跟last_insert_id
,但是如果要添加50项,则需要几秒钟至少这对用户体验并不好。
sql_task.query("INSERT INTO `ItemDB` (`ItemName`, `Type`, `Time`) VALUES ('%s', '%d', '%d')", strName.c_str(), uiType, uiTime);
获取ID:
uint64_t item_id { sql_task.last_id() }; //This calls mysql_insert_id
答案 0 :(得分:1)
我相信你需要稍微重新考虑你的设计。让我们使用销售订单的类比。使用销售订单(或发票#),用户可以获得发票编号(auto_incr)以及多个行项目编号(也包括auto_inc)。
选择销售订单和所有订单项进行插入(来自GUI)并执行插入。首先,插入销售订单行,并将其ID保存在变量中,以便后续调用以插入行项目。但是,只是插入行项目而不立即返回其auto_inc id值。应用程序最终只返回销售订单号。您的应用在后续通话中如何使用该销售订单号取决于您。但是不需要立即检索所有X行或50行,因为它具有冰冻并保存在某处的销售订单号。我们称之为销售订单编号XYZ。
当您确实需要这些信息时,示例调用可能看起来像
select lineItemId
from lineItems
where salesOrderNumber=XYZ
order by lineItemId
您需要记住,在多用户系统中,无法保证接收连续的数字块。对您来说也不重要,因为它们都附有正确的销售订单号。
同样,以上只是一个类比,用于说明目的。
答案 1 :(得分:0)
这是一个常见但很难解决的问题。不确定mysql,但PostreSQL使用序列生成自动ID。插入框架(对象关系映射器)在期望插入许多值时使用它们:它们直接查询序列中的一堆ID,然后使用已知的ID插入新行。这样,每次插入后都不需要额外的查询来获取ID。
缺点是当不同的编写者混合他们的插入时,关系ID - 插入时间可以是非单调的。这对数据库来说不是问题,但有些(写得不好?)程序可能会有所期待。
答案 2 :(得分:-1)
由于您的ID是自动增量的,因此在SELECT
次查询之前和之后,您只能进行两次INSERT
次查询:
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name = 'dbTable' AND table_schema = DATABASE();
--
-- INSERT INTO dbTable... (one or many, does not matter);
--
SELECT LAST_INSERT_ID() AS lastID;
这将为您提供第一个和最后一个插入ID之间的序列。然后你可以很容易地计算它们的数量。