3

所以我的应用需要让用户生成随机的字母数字代码,如 A6BU31、38QV3B、R6RK7T。目前它们由 6 个字符组成,而 I 和 O 没有被使用(所以我们得到了 34^6 种可能性)。然后将这些代码打印出来并用于其他用途。

我现在必须确保许多用户每次请求最多可以“保留” 100 个代码,因此用户 A 可能想要获得 50 个代码,用户 B 想要生成 10 个,依此类推。这些代码在所有用户中必须是唯一的,因此用户 A 和用户 B 可能不会同时收到代码 ABC123。

我目前的方法(使用 PHP 和 MySQL)是为此设置两个 InnoDB 表:

  • 一个(“存储库”)包含大量预先生成的代码(因为冲突的可能性会随着时间的推移而增加,我不想采用 try-insert-if-fails-try-another-code 方法)。存储库只包含代码和一个自动递增的 ID(所以我可以对它们进行排序,见下文)。
  • 另一个表保存保留的键(即代码+拥有用户)。

每当用户想要保留 N 个密钥时,我计划执行以下操作

BEGIN;
INSERT INTO revered_codes (code,user_id)
  SELECT code FROM repository WHERE 1 ORDER BY id LIMIT N;
DELETE FROM repository WHERE 1 ORDER BY id LIMIT N;
COMMIT;

应该有效,但我不确定。好像我正在构建一个 WTF 解决方案。

插入后,我必须选择刚刚保留的代码以将它们显示给用户。这是棘手的部分,因为在我的交易完成后,我真的不知道如何识别刚刚保留的代码。我当然可以在我的reserved_codes表中添加另一列,持有某种随机令牌,但这似乎更WTFy。

我最喜欢的解决方案是有一个随机数序列,这样我就可以在表中执行INSERT操作。reserved_codes

那么,如何在 MySQL 中实现这个独特的、随机的和事务安全的序列呢?一个想法是在reserved_codes表上定期自动递增并从该数字列中获取随机代码值,但我想知道是否有更好的方法。

更新:我忘了提到拥有一个相当小的保留代码表是有利的,因为我以后必须再次找到单个代码来更新它们(reserved_codes它有几个属性)。所以让保留表缓慢增长是好的(而不是在大约 1mio 预生成代码上拥有巨大的索引)。

4

1 回答 1

3

如果您已经有一个存储库表,我只需添加一个用户列,然后运行此查询:

UPDATE repository SET user_id = ? WHERE user_id IS NULL LIMIT N;

之后,您可以再次选择记录。这有两个明显的缺点:

  • 你需要一个索引user_id
  • 除了将其绑定到用户之外,您不能将表中的代码用于其他任何事情。
于 2012-05-02T02:27:48.853 回答