使用最少的资源使用来检查数据库的唯一随机值

时间:2016-03-03 12:24:49

标签: php mysql database unique

这是一个最佳实践问题。我使用以下参数生成随机字符串标识符:

  • 长度:7个字符
  • 种子:A-Za-z0-9(小写+大写字母和数字)

我需要在插入之前检查数据库中是否存在该字符串。我可以通过两种方式做到这一点:

  1. 运行do...while循环。在其中,生成随机字符串,每次使用COUNT(*)查询数据库,直至count === 0
  2. 首先使用单个查询从数据库中获取所有现有的唯一字符串,然后运行do...while循环以生成不在获取的数组中的随机字符串。
  3. 对我来说很明显,第二种方法在技术上对数据库服务器的资源密集程度较低,因为只有一个查询,而不是一遍又一遍地查询。所以我倾向于这种方法,但我看到两个潜在的警告:

    大型数据库,以及在提取和插入之间传递的时间。

    • 大型数据库结果:在我需要考虑切换到第一种方法之前,查询结果中可以有多少行?换句话说,何时数据库服务器上的大结果集的压力低于运行多个后续查询? 1000个结果? 5000? 20000

    • 获取和获取之间的时间插入:如果我使用第二种方法,当两个或多个用户尝试同时运行相同的功能时,我会发现存在风险。第一个用户的结果集(从数据库中获取的唯一字符串)可能不包括在查询后2ms刚刚添加的其他用户的唯一字符串。这可能会在数据库中产生重复。

    第二种方法在生产中是否真的可行,或者它只是一个梦想?

1 个答案:

答案 0 :(得分:1)

第二种选择对我来说似乎不切实际。如果表中只有几行,则冲突风险较低,如果有很多行,则会增加冲突的风险,但在php端获取所有行的内存效率不高。

第一种解决方案对我来说似乎更好。

但我认为可以使用第三种选择。在MySQL中为随机值添加唯一索引。生成随机值,然后尝试插入它。如果发生碰撞,请抓住错误。这是有效的,因为MySQL在检索索引时是否存在快速检查值是否存在。这种方法没有并发问题。

唯一的警告(对于所有方法)是当表中的行数很高时,您将很难找到尚未使用的值。要降低碰撞风险,可以增加随机值的大小。您还可以创建另一个包含未使用值的表,并在其值太少时使用其他算法填充此表。