gpt4 book ai didi

mysql - 在 MySQL 中实现 ids 线性同余生成器的巧妙方法?

转载 作者:行者123 更新时间:2023-11-29 13:49:20 26 4
gpt4 key购买 nike

一些介绍:在考虑了将在 URL 和其他地方公开使用哪种唯一 id 之后,我选择了线性同余生成器 ( http://en.wikipedia.org/wiki/Linear_congruential_generator )。为什么不使用 UUID 或自动递增?

  • UUID 太长,难以存储在数据库中(推荐的方法是将它们转换为 VARBINARY(16))。
  • Auto_increment 公开了新实体的注册和添加顺序,并提供了预测下一个 id 的能力。例如,如果一项服务变得流行,用户可以进行多次注册以获得一个不错的ID,然后尝试出售这样的帐户,ID会给出某种状态:注册越早越酷。我宁愿避免这样的事情。

使用 LCG,序列是随机的,我可以选择参数,以便可能的值能够很好地适合特定目的的数据类型。例如,对用户 ID 使用 INT UNSIGNED 并选择参数以给出周期 2^32。

问题是要生成下一个 id,我需要获取最后一个 id 的值:

nextId = (a * lastId + c) % m
  1. 据我了解,我必须自己设置第一个 id ?我选择哪个数字重要吗?
  2. 生成新 ID 的巧妙方法是什么?也许创建一个表,其中包含每个表最后生成的 id 列表?或者向每个表添加一个 auto_increment 列以跟踪最后生成的 id?当短时间内注册量较多时,如何避免出现问题?

更新1:我找到了一种使用此处信息对多用户安全的方法: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();

最佳答案

为了在 MySQL 中可靠地完成此操作,您需要编写一个存储过程,并使用其中包含最新 ID 的单行表。

您的存储过程需要锁定表、读取最新 ID、生成新 ID、将其更新到表中、解锁表并将新 ID 返回给调用者。

您还可以保留一个多行表,其中包含您生成的 ID 列表。在这种情况下,您的存储过程需要锁定、读取最近生成的 ID、生成一个新ID、将其插入表中、解锁并返回。显然,在这种情况下,您将需要一种可靠的方法来查找最近生成的 ID。也许使用自动增量列和 ID 列就可以解决问题。

实现您想要的效果的另一种方法是编写一个存储过程来生成多位随机数(我会使用至少 48 个二进制数字),然后尝试将其插入作为表的主键。只要由于 key 冲突导致插入失败,就尝试另一个随机数。这些长随机数比 LCG 序列更难预测。

开发存储过程后,在将其投入生产之前,您必须在繁重的多客户端负载下对其进行严格测试。如果您没有充分测试,您将会感到遗憾。根据经验,我知道这些东西很难做好。

UUID 确实存在您提到的大小缺点。但它有一个非常强大的优势:它经过了彻底的测试。如果你选择了它,你就不需要尝试重新发明轮子。 (根据我重新发明车轮的经验,我想出了一些扁平轮胎。)

关于mysql - 在 MySQL 中实现 ids 线性同余生成器的巧妙方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16906543/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com