我正在创建一个生成唯一键的系统。它现在有效。但是,我还没有对很多用户进行过测试。用户可以单击按钮然后获取其唯一编号,就像这样简单。
但是,如果他们在同一时间完全按下按钮(即使是以ms为单位),如何防止多个用户获得相同的唯一键?按钮在客户端,所以我必须在后端做一些事情。
这是唯一的关键看起来像:
19/XXXXXX-ABC/XYZ
XXXXXX
是从000001
到999999
的自动增量编号。我有这个代码,但不知道它是否足够可靠来处理我的问题。
$autoinc = $this->MPenomoran->get_surat($f_nomor)->jumlah_no+1; //count data in table and added 1
$no_1 = date('y')+2;
$no_2 = str_pad($autoinc, 6, '0', STR_PAD_LEFT);
$no_3 = "-ABC/XYZ";
$nomor = $no_1."/".$no_2.$no_3;
$returned_nomor = $nomor;
$success = array ('nomor' => $returned_nomor); //sent unique keys to user's view
答案 0 :(得分:2)
您似乎不想出来告诉我们这个平台是什么,或者该平台的限制是什么。
跳出来的第一件事是您的格式受到年份限制,总共999999个唯一键。非常奇怪,但可能你理解这个限制,并且需要输入一些代码来处理达到最大数量。
<强>途径强>
基于REDIS
使用INCR的REDIS服务器非常简单。既然INCR是原子的,那么你基本上只需要创建一个名为你的年份+ 2的密钥,如果它不存在,并且从那里开始使用INCR就可以得到一个解决方案。
你需要利用一些php redis client,其中有各种各样的优点和缺点,我不打算进入。
Redis也非常适合缓存,所以如果可能的话,这是我要研究的第一件事。
基于MySQL
使用mysql有一些不同的解决方案。他们参与其中,所以我只是概述它们,因为我不想花时间写小说。
注意: Y 您需要将这些转换为相应的PHP代码(mysqli或PDO),如上所述,参数传递,交易开始等的
MySQL - 创建自己的序列生成器
使用以下基本结构创建名为“Sequence”的表:
name varchar(2) PK
nextval unsigned int default 1
发动机= InnoDB的
基础查询将是这样的:
BEGIN_TRANS;
SELECT nextval FROM Sequence WHERE name = '$no_1' FOR UPDATE;
UPDATE Sequence SET nextval = nextval + 1;
END_TRANS;
此代码模拟序列化的Oracle样式序列。从并发的角度来看是安全的,因为MySQL会短暂锁定行,然后在完成后递增它。
MySQL - 多值PK的自动增量
这有一些警告。
它通常与复制不兼容。 基础表必须是myisam
name varchar(2) PK
lastval unsigned int AUTO_INCREMENT PK
engine=MyISAM
您的基础查询将是:
INSERT INTO Sequence (name) VALUES ('$no_1')
这取决于支持多列键的mysql,其中第二列是AUTO_INCREMENT。它的行为使得它就像每个唯一名称的序列一样。
然后,您将使用相关的api内置方法来获取mysql LAST_INSERT_ID()。例如PDO
其他替代方案
您还可以使用信号量,带锁定的文件以及各种其他想法来创建一个序列生成器,该序列生成器可以在单片(一个服务器用于所有内容)环境中很好地工作。 MySQL和Redis将服务于一个集群,因此从这个角度来看,这些是更强大的选择。