因此,想象一个mysql表,其中包含一些简单的列,一个自动增量和一个哈希(varchar,UNIQUE)。
是否可以为mysql提供一个将添加列的查询,并生成一个没有多个查询的唯一哈希?
目前,我能想到实现这一目标的唯一方法是暂时,我担心数据库中的条目越多,处理器越来越密集。
这里有一些伪php,显然是未经测试的,但是得到了一般性的想法:
while(!query("INSERT INTO table (hash) VALUES (".generate_hash().");")){
//found conflict, try again.
}
在上面的示例中,哈希列将是UNIQUE,因此查询将失败。问题是,数据库中有500,000个条目,我正在使用base36哈希生成器,有4个字符。冲突的可能性几乎是1/3,我肯定无法运行160,000个查询。事实上,我认为任何超过5个都是不可接受的。
那么,我可以用纯SQL做到这一点吗?我需要生成一个base62,6字符串(如:“j8Du7X”,字符az,AZ和0-9),并用它更新last_insert_id,或者甚至更好,在插入过程中生成它。
我可以使用MySQL处理基本的CRUD,但即使是JOIN也不在我的MySQL舒适区之外,所以请原谅我的无知,如果这是蛋糕。
有什么想法吗?我更喜欢使用纯MySQL或PHP& MySQL,但是,如果另一种语言可以干净利落地完成,我也会构建一个脚本和AJAX。
谢谢!
答案 0 :(得分:3)
如果您的心脏被设置为使用base-36 4个字符哈希(哈希空间仅为1679616),则您可能预先生成一个哈希表,该哈希表不在另一个表中。然后找到一个唯一的哈希就像将它从“未使用的表”移动到“使用的表”(即O(1))一样简单。
如果您的表格可能是1/3已满,您可能需要考虑扩展哈希空间,因为它可能会填满您的生命周期。一旦空间已满,无论您使用何种算法,都将无法再找到独特的哈希值。
答案 1 :(得分:2)
这是我们用于类似项目的方法,我们希望生成唯一的优惠券代码。
首先,我们使用了AUTO_INCREMENT主键。这样可以确保唯一性和查询速度。 然后,我们使用A,B,C等(而不使用O和I)创建了base24编号系统,因为有人可能认为它们是0或1。 然后,我们将自动递增整数转换为我们的base24数字。例如0 = A,1 = B,28 = BE,1458965 = EKNYF。我们使用base24,因为base10中的长数字在base24中具有较少的字母。
然后,我们在表中创建了一个单独的列,即coupon_code。没有被索引。
我们取了base24并添加了3个随机数或I和O(在base24中未使用),然后将它们插入到我们的数字中。例如,EKNYF可以变成1EKON6F或EK2NY3F9。这是我们的优惠券代码,我们将其插入了coupon_code列。它是唯一且随机的。
因此,当用户使用代码EK2NY3F9时,我们要做的就是删除所有未使用的字符(2、3和9),然后得到EKNYF,我们将其转换为1458965。我们只需选择主键1458965和然后将coupon_code列与EK2NY3F9进行比较。
我希望这会有所帮助。
答案 2 :(得分:1)
哈希是什么哈希?您似乎只想要一个随机生成的唯一VARCHAR列?自动增量出了什么问题?
无论如何,你应该使用更大的哈希 - 找到一个MD5函数 - (如果你实际上是哈希的东西),或者一个超过4个字符的UUID生成器,是的,你可以使用while循环,但只是产生足够大的冲突是非常不可能的
答案 3 :(得分:1)
正如其他人所说,autoinc字段有什么问题?如果你想要一个字母数字值,那么你可以简单地从int转换到36中的字母数字字符串。这几乎可以用任何语言实现。
答案 4 :(得分:0)
与zneaks发表评论,为什么不使用自动增量色谱柱?将哈希保存在另一个(非唯一)字段中,并将id连接到它(动态)。所以你给用户[hash] [id]。您可以使用substring
函数在纯SQL中解析它。
由于您必须拥有哈希值,因此用户无法通过递增ID来查看其他记录。
答案 5 :(得分:0)
所以,为了防止有人遇到类似问题,我正在使用UNIQUE字段,我将使用php哈希函数来插入哈希值,如果它返回错误,我会再试一次。 希望由于冲突的可能性很小,它不会变慢。
答案 6 :(得分:0)
您还可以检查MySQL函数UUID()和UUID_SHORT()。这些函数根据定义生成全局唯一的UUID。您不必仔细检查PHP生成的哈希字符串是否已存在。
我认为在某些情况下,这些功能也可以满足您项目的要求。 : - )