来自主键的唯一URL

时间:2012-08-16 16:39:52

标签: php mysql primary-key

我正在尝试在外观和行为方面创建类似于youtube的/v=xxx的网址。简而言之,用户将上传文件并能够通过该URL访问它们。此URL代码需要是数据库主键的某种形式,因此页面可以收集所需的数据。我是数据库新手,这比数据库问题更重要。

在我的数据库中,我有一个自动增量主键,可以访问文件数据。我想使用该数字来创建文件的URL。我开始研究不同的哈希函数,但我担心会发生冲突。我不想为两个不同的文件使用相同的URL。

我还考虑使用uniqid()作为我的主键CHAR(13),并直接使用它。但有了这个,我担心效率。另外环顾四周我似乎找不到太多关于它的东西,所以这可能是一个奇怪的想法。更不用说我需要在生成ID时测试碰撞,这可能是低效的。自动增量更容易。

这有什么好的解决方案吗?我的任何一个想法都有效吗?如何从自动递增的主键生成唯一的URL并避免冲突?

我倾向于我的第二个想法,它不会非常有效,但是当需要将数据添加到数据库(测试碰撞)时会产生最大的性能缺陷,这对于最终用户来说只会发生一旦。另一个性能缺点可能在于实际查看字符而不是整数。但我主要担心这是不好的做法。

编辑:

一个简单的解决方案就是直接使用自动递增的值。叫我挑剔,但那看起来很难看。

4 个答案:

答案 0 :(得分:1)

生成非碰撞短哈希确实会令人头疼。因此,Stackoverflow的slug格式非常有前途,并保证生成非重复的url。

例如,同样的问题有

  

https://stackoverflow.com/questions/11991785/unique-url-from-primary-key

在这里,它具有唯一的主键和标题,使其更加友好。


然而,如评论所述,他们之前提出的问题很少,可能会清楚,为什么?你正在尝试的东西最好被遗漏。

  1. How to generate a unique hash for a URL?
  2. Create Tinyurl style hash
  3. 创建短哈希会增加碰撞的可能性,因此更好的用户base64sha512可以创建安全哈希。

答案 1 :(得分:0)

您可以简单地对时间进行哈希,然后检查该哈希值(或数据库中该哈希值的一部分)。 如果你在数据库中的那个字段上设置一个索引(并确保哈希足够长,不会产生很多冲突),那么它在任何时候都不会成为一个问题。

<?php

$hashChecked = false;

while( $hashChecked === false ){
  $hash = substr( sha1(time().mt_rand(9999,99999999)), 0, 8);  //varchar 8 (make sure that is enough with a very big margin)
  $q = mysql_query("SELECT `hash` FROM `tableName` WHERE `hash` = '".$hash."'");
  $hashChecked = mysql_num_rows() > 0 ? false : true;
}

mysql_query("INSERT INTO `tableName` SET `hash` = '".$hash."'");

答案 2 :(得分:0)

如果您愿意使用随机数生成短网址,这是相当简单的。例如,您可以这样做:

 SELECT BASE64_ENCODE(CAST(RAND()*1000000 AS UNSIGNED INTEGER)) AS tag

这能够为您提供一百万种不同的标签。要获得更多可能的标记,请增加RAND()数乘以的值。这些标签值很难预测。

为确保不会出现重复项,您需要重复删除标记值。这很容易,但需要程序中的逻辑。将标记值插入到将其用作主键的表中。如果插入失败,请再试一次,重新调用RAND()。

如果接近最大标签数量,您将开始出现大量插入失败(标签冲突)。

BASE64_ENCODE来自您需要安装的存储功能。你可以在这里找到它:

http://wi-fizzle.com/downloads/base64.sql

如果您使用的是MySQL 5.6或更高版本,则可以使用内置的TO_BASE64功能。

答案 3 :(得分:0)

我想做类似的事情(但有文章,而不是上传的文件),并提出了一些不同的东西:

  • 取一个素数[y](很多)大于文件的最大数[n](例如25000对于文件总数来说足够大,而1000099比一个大得多的素数比25001)
  • 表示当前文件id [x] :( x * y)模数(n + 1)
  • 这将生成1到n之间永不重复的数字

尽管url可能看起来像传统的主键,但它确实具有以下优点:每个后续文档的id都与前一个文档完全无关;有些人还认为,不包括主键也具有非常小的安全优势......