生成数据库条目的计数器代码

时间:2011-08-30 00:42:28

标签: php mysql

我正在使用PHP / MySQL,在打开输入屏幕时为每个条目生成计数器代码。

以下是我正在使用的代码

$qresult = $db->query("SELECT count(*) FROM ap_aurora_projects");
$row = $qresult->fetch_row(); 
$slno = $row[0] + 1;

$today = date("ymd");

$code = $today . "-" . $slno;

此代码正确生成并在创建记录之前向用户显示。问题是当多个用户同时打开代码在屏幕上重复时。

避免重复的方法是什么。

我尝试创建一个单独的表来存储最新的数字并为每个请求递增,但问题是,如果用户取消该条目,则该数字将丢失。

修改

当一个用户生成代码并插入记录时,代码正常工作。但问题是如果多个用户同时打开,它会在屏幕上为它们生成相同的号码。如果所有人都试图保存记录,那么它就会重复。 请注意,我生成此号码并在输入屏幕中显示最初不是在保存记录时。

3 个答案:

答案 0 :(得分:7)

我认为您在问题中显示的代码已经过简化,您不能按照另一个答案的建议使用AUTO_INCREMENT列。

您需要锁定表格以供阅读,直到更新为止。按以下顺序执行MySQL查询:

LOCK TABLES ap_aurora_projects READ;
SELECT count(*) FROM ap_aurora_projects WHERE ...;
//Update here ...
UNLOCK TABLES;

有关锁定整个表的更多信息,请访问: http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html

如果您使用的是InnoDB存储引擎,可以在此处阅读有关高级(行)锁定和事务的更多信息: http://dev.mysql.com/doc/refman/5.6/en/innodb-transaction-model.html

答案 1 :(得分:6)

以下是您需要做的事情:

首先,创建一个表:

create table uniqueId ( id bigint(20) unsigned not null auto_increment primary key );

其次,使用此代码(我不知道您使用哪个MySQL代码,因此我将使用常用的代码):

$link = mysql_connect('localhost', 'user', 'password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');
mysql_query("INSERT IGNORE INTO uniqueId VALUES (NULL);");
printf("Last inserted record has id %f\n", date("ymd") . "-" . mysql_insert_id());

通过插入而不是选择,您确定不会有重复。

答案 2 :(得分:4)

如您所发现的那样,创建自己的自动增量标识符很困难且容易出错。您应该考虑使用MySQL AUTO_INCREMENT feature和相应的LAST_INSERT_ID()函数,该函数将返回该会话中最近插入的记录的ID

该链接的主要摘录:

  

这些函数是特定于连接的,因此它们的返回值是   不受另一个同时执行插入的连接的影响。

但是你必须改变你的方法。您不必在创建记录之前在屏幕上显示ID,而是需要等到记录的插入。或者,如果您真的需要显示此ID,则插入空白记录以创建并返回ID,然后从用户输入的数据中编辑该记录,而不是执行插入。

一个令人担忧的想法是,您需要向系统用户显示内部主键。密钥不是自然的(如政府颁发的标识符),它由系统生成。这闻起来有点糟糕的设计。通常,主键值永远不会显示给用户,并且会使用其他一些代理标识符。