一点介绍:在思考将在URL和其他地方公开的哪种独特ID之后,我选择了线性同余生成器(http://en.wikipedia.org/wiki/Linear_congruential_generator)。 为什么不UUID或自动递增?
使用LCG,序列是随机的,我可以选择参数,以便可能的值很好地适合特定目的的数据类型。例如,对用户ID使用INT UNSIGNED,并选择参数以给出2 ^ 32的周期。
问题是要生成下一个id,我需要获取最后一个id的值:
nextId = (a * lastId + c) % m
UPDATE1: 我发现了一种使用此处信息的多用户安全方法:http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id
CREATE TABLE sequences (users INT UNSIGNED NOT NULL, posts BIGINT UNSIGNED NOT NULL);
INSERT INTO sequences VALUES(123456,123456789);
然后获取新ID:
UPDATE sequences SET users=LAST_INSERT_ID((a * users + c) % m);
SELECT LAST_INSERT_ID();
答案 0 :(得分:1)
要在MySQL中可靠地执行此操作,您将需要编写存储过程,并使用包含最新ID的单行表。
您的存储过程需要锁定表,读取最新ID,生成新ID,将其更新到表中,解锁表,然后将新ID返回给调用者。
您还可以使用已生成的ID列表保留多行表。在这种情况下,您的存储过程需要锁定,读取最近生成的 ID,生成一个新ID,将其插入表中,解锁并返回。显然,在这种情况下,您将需要一种可靠的方法来查找最近生成的ID。也许使用自动增量列和ID列可以解决问题。
实现所需内容的另一种方法是编写一个生成多位数随机数的存储过程(我用至少48个二进制数字),然后尝试将其作为表的主键插入。只要插入因密钥冲突而失败,请尝试另一个随机数。这些长随机数比你的LCG序列更难预测。
在开始生产之前,您必须在开发过程中严格按照繁重的多客户端负载测试存储过程。如果你没有充分测试,你将抱歉。我根据经验知道这些东西很难做对。
UUID确实有你提到的尺寸劣势。但它有一个非常强大的优势:它已经过彻底的测试。如果选择它,您无需尝试重新发明轮子。 (根据我的经验,重新发明轮子,我想出了一些扁平轮胎。)