我有三个表:用户,其中包含唯一的nickname
,超过四百个名称,300000个加上形容词和一个大量可能的组合。
订阅时,用户可以通过将随机名称与随机形容词组合来生成唯一,随机且有希望的有趣昵称。用户单击按钮和Voilà!令人振奋的身份诞生了。
我通过为每个人运行两个查询来选择随机名称和形容词:
SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM names/adjectives
和
SELECT * FROM names/adjectives LIMIT offset, 1
然后我检查用户是否不幸生成已存在的身份。
SELECT COUNT(nickname) FROM users WHERE nickname=:generatedNickname
如果他是这个可怜的家伙,我会再次循环,直到它解决了一些事情。
但是,正如你们可能已经想到的那样,用户群的增长也意味着更长的循环以及来自我虚弱的EC2 Tier 1 Matchbox的更多汗水。所以我想出了一个出色的解决方案:如果我预先生成所有可能的组合并将它们放入一个巨大的桌子中会怎么样?这将允许简单的采取和播放操作,而我会啜饮担心在一些匿名海滩上免费马提尼酒还是我?我谦逊的LAMP实体是否会在巨大的桌子(男性和女性)的光荣景象中颤抖和逃离?有没有更好的解决方案?
答案 0 :(得分:1)
预先生成这些组合将导致大量数据。我不推荐它。我的建议是使用比RAND()
更好的随机性来源。碰撞的可能性(基于您的估算)仅在n/120000000
左右,其中n
是用户数量,因此如果您做<循环,您的循环将无法运行很长时间/ em>得到一个。
答案 1 :(得分:1)
为名词和形容词提供AUTO_INCREMENT
个PRIMARY KEY
的ID。另一列(名词/形容词)应为UNIQUE
。
为这两张桌子中的每一张都保留COUNT(*)
。如果您修改了表格,请重新计算这些计数。不要在下面的代码中执行SELECT COUNT(*)
,它会进行表扫描 - 不便宜。
使用SELECT noun FROM Nouns WHERE id = CEIL(noun_count * RAND())
获取随机&#34;名词&#34;。同上&#34;形容词&#34;。
现在我们需要检查重复项。你已经在用户表中存储了形容词 - 名词组合,对吗?它是INDEXed
,对吗?因此,只需检查此组合已经使用过。
如果是重复,请重新开始。
这些步骤都不需要很长时间,所以即使你必须(很少)重复这个过程,也不会花很长时间。
PS:我认为你会发现RAND()
足以完成这项任务。