【发布时间】:2018-05-07 17:28:46
【问题描述】:
我必须为发票创建唯一 ID。每个发票 ID 的格式为 year-month-number,其中包含发票的当前年份和月份以及一个从 1 开始的递增数字(不允许有间隙)。
例如,如果我们在 2017 年 1 月有 4 张发票,我将有以下 4 个发票 ID:
2017-1-1
2017-1-2
2017-1-3
2017-1-4
现在我想创建一个创建这些唯一 ID 的应用。特别是我想确保即使 2 个人同时请求发票号码,他们也应该得到不同的 ID。
我正在使用 InnoDB,我有下表
书
year | month | number |
------------------------
2017 | 7 | 2 |
2017 | 6 | 5 |
2017 | 5 | 6 |
如果尚未为year-month 对创建发票,则数据库中没有条目。主键是 year-month 对,number 是 auto increment index。
假设我会像这样计算下一个发票 ID:
$stmt = $db->prepare('INSERT INTO book(year,month,number)
VALUES (?,?,1)
ON DUPLICATE KEY UPDATE number= LAST_INSERT_ID(number+1)');
$stmt->bind_param('ii', $year, $month);
$stmt->execute();
echo 'Next invoice id: ' . $year . '-' . $month . - . $db->insert_id;
解释:$db->insert_id; 返回列号,因为它的 auto increment column 和 LAST_INSERT_ID(number+1) 增加了最后插入的 number(也可能是由不同的用户?我不确定,我有问题在文档http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id 中找到它)
这段代码真的有效吗,或者如果人们同时执行这段代码,它可能会创建多个相同的 id?
编辑 假设当前月/年数为 5。 为什么不能 2 个人同时计算发票,以便两个查询同时将数字 5 升级到 6?在这种情况下,他们都会得到发票 ID '2017-11-6' 对吗?
【问题讨论】:
-
你没有人工智能专栏吗?如果没有,您应该这样做,因为这会自动使所有记录唯一。
-
@Fred-ii-
number字段是AI列,但我会通过更新增加它。 -
你不应该为它增加AI,它会自己增加。我觉得我没有完全理解你想在这里做什么。您可以将
mysqli_error($db)添加到查询中并查看返回的内容吗? -
@Fred-ii- 你是对的,这是使用
AI字段的一种非常不寻常的方式。但是字段number只是一个AI键,因此它会被$db->insert_id;返回。事实上,它甚至不是独一无二的。可以同时是数据库中的2017-7-2和2017-8-2。但是2017-7-2和2017-7-3是不可能的。我从这里 (stackoverflow.com/a/38544279/2311074) 发现了这个技巧,但我只是不确定它是否会给两个不同的用户提供相同的发票 ID。 -
Hm....... -
001等与number列相关吗?and number is an auto increment index不会以前导零递增,因此您可能必须找到另一种方法来做到这一点(我以前在某处看到过)并为其添加另一列,id作为 AI 并删除/ ALTER 当前的 AI'd 列。也许我没有收到您的问题/相关专栏和00X_integer,所以我可能对此没有更多帮助,对不起亚当。希望我能在这方面提供更多帮助。看看其他人是否可以提供(另一个)帮助。
标签: php mysql innodb auto-increment