MySQL长表的唯一随机字符串最佳方法

4

我知道如何在PHP和MySQL中创建随机字符,但问题是我必须为大约10,000行的表格创建一个4个字符的随机字符串。什么方法最好确保它保持唯一性?

如果需要,我可以使用更长的字符串,但不能超过12个字符。

为了简单起见,表格已经存在,我需要添加一个额外的列并填充它以获得4个字符的随机字符串,并且键必须保持唯一。


需求不太清楚 - 您是想使用这个新的随机长度随机值字符串更新表格,并确保每一行都是唯一的吗?这似乎意味着每一行都必须获得一个新的随机长度随机值字符串? - p.campbell
我下面的回答是否误解了你的问题?你是想让每个完整的字符串都是唯一的,还是你想让你的字符串中的每个4个或更多字符都是唯一的? - THE DOCTOR
我已经读了这个问题4遍,但它并没有明确说明。问题和评论中是一些碎片化的陈述,没有连贯地放在一起,以明确阐述所需的内容。请注意不要对那些愿意帮助的人说话过于简单,否则你的问题可能会得不到回答。 - p.campbell
6个回答

3
一个选项:
将所有可能的字符放在一个只有一列的表格中。
val
------
0
1
...
9
a
b
...
z

请使用以下查询。
SELECT CONCAT(a.val,b.val,c.val,d.val)
FROM chars AS a
JOIN chars AS b
JOIN chars AS c
JOIN chars AS d
ORDER BY RAND()
LIMIT 10000

另一方面,如果您需要逐个获取ID,则有两种方法。
A. 如果有很多未分配的ID可用。
在这种情况下,您只需生成一个ID并查看它是否可用。如果不行,请尝试另一个。
B. 如果您想保留已分配的ID和可用的ID数量相同。
在这种情况下,最好预先生成所有ID,将它们混洗,并在需要时选择下一个可用的ID。比如将它们全部放入一个表格中,当您从该表格中分配一个ID时,就将其删除,以便不能再次选择。
如果您允许使用的字符是0-9a-z,则意味着该表格将占用364。那只是几MB而已。

@Alin:谢谢你的回答,但问题是表格不会停止,我每天都要插入数据。 - user529649
答案取决于可能的ID数量和/或每次需要检索的数量。 - Alin Purcaru
现在大约有10,000个,每天增长20-50个。 - user529649
@Omeid Herat 不,我的意思是你可以用这4个字符生成多少个?允许使用哪些字符? - Alin Purcaru
1
你已经拥有了所有需要做出决定的信息。根据我对你的情境的理解,我会给出一个个人偏好:将ID设置为6个字符长度,并在添加内容时生成ID,直到找到一个空闲的ID为止。如果您想确保只进行一次尝试,则可以保留预先生成的空闲ID列表。并且可以使用cron或其他方式定期向该列表添加内容。 - Alin Purcaru
@Alen 谢谢你的回答,我喜欢第二种方式。 - user529649

2
由于这些字符串需要唯一,为什么不使用数字自动增量值,然后将其转换为基于字符的值,类似于十进制转换为十六进制。
如果您选择例如所有字符和数字,则只需创建一个将整数转换为“基数62”数字的例程即可。

一个好主意。唯一的问题是生成的字符串不会是随机的。 - Alin Purcaru
当我需要根据这些信息检索行时,我需要对其进行解码,对吗? - user529649
@Alin:是的,但“随机”和“唯一”在某种程度上是相互矛盾的。@Omeid:不一定,因为您可以使用“生成”的值来检索数据。 - user330315
在我看来,同时实现随机性和唯一性似乎是要解决的真正问题。虽然两者都可以实现,但并不是直观的。请查看我的答案以了解更多信息。 - Alin Purcaru

0
你可以使用关键字 DISTINCT
例如,以下查询将仅返回唯一的行,您可以通过这些行验证您的 4 个字符随机字符串是否仍然是唯一的:
mysql> SELECT DISTINCT random_strings FROM chars;

谢谢您的回答,但我希望在那里有这些值,我想为每一行创建长度为四的随机字符。 - user529649

0

这可能会很冗长,但可以让您创建所需的内容:

 CREATE FUNCTION gen_alphanum () RETURNS CHAR(4)
    RETURN 
    ELT(FLOOR(1 + (RAND() * (50-1))), 'a','b','c','d','e','f','g','h','i','j','k','l','m  ','n','o','p','q','r','s','t','u','v','w','x','y', 'z',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y', 'Z',);
    )

0

看起来你已经在MySQL中编写了创建这些随机值字符串的代码。

考虑以下选项:

  • 在MySQL中创建一个用户定义函数。让该函数运行SQL语句以生成并返回此新的随机字符串。确保在创建语句中使用NOT EXISTS(SELECT MyRandomString FROM MyTable)来检查该随机字符串是否已存在于表中。

  • 插入新行时,使用此函数的返回值分配给MyRandomString列。

  • 要更新现有数据,只需:

 UPDATE MyTable
 SET    MyRandomString = fn_CreateSomeRandomString()
  • 插入时:
 INSERT INTO MyTable (foo, bar, MyRandomString) 
 VALUES ('','', fn_CreateSomeRandomString());

这里有一个在PasteBin上的UDF示例


0
如果您使用的是MySQL 5.6,您可以按照以下方式使用TO_BASE64:
select LEFT( TO_BASE64( SHA(rand()) ), 6 ) ;

如果您没有5.6版本,

DELIMITER //

drop function if exists randChr //
create function randChr()
returns char
BEGIN
  IF RAND() <= 0.5 THEN -- Lowercase
    return CHAR( 97 + 25*rand() ) ;
  ELSE -- uc
    return CHAR( 65 + 25*rand() ) ;
  END IF;
END //

drop function if exists randString //
create function randString( len int )
returns varchar(255)
BEGIN
  SET @n = 0;
  SET @res = '' ;
  REPEAT
    SET @res = concat( @res, randChr() ) ;
    set @n = @n + 1 ;
  UNTIL @n >= len END REPEAT;
  return @res ;
END //

DELIMITER ;

-- USE:
select randString( 5 );
select randString( 60 );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接