Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 主键中的唯一url_Php_Mysql_Primary Key - Fatal编程技术网

Php 主键中的唯一url

Php 主键中的唯一url,php,mysql,primary-key,Php,Mysql,Primary Key,我正在尝试创建一个在外观和行为上与youtube的/v=xxx类似的URL。简而言之,用户将上传文件,并能够通过该URL访问它们。此URL代码需要是数据库主键的某种形式,以便页面可以收集所需的数据。我是数据库新手,这更像是一个数据库问题 在我的数据库中,我有一个自动递增的主键,它可以访问文件数据。我想用这个数字来创建文件的URL。我开始研究不同的散列函数,但我担心冲突。我不希望两个不同的文件使用相同的URL 我还考虑使用uniqid()作为我的主键CHAR(13),直接使用它。但我担心的是效率。

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

在我的数据库中,我有一个自动递增的主键,它可以访问文件数据。我想用这个数字来创建文件的URL。我开始研究不同的散列函数,但我担心冲突。我不希望两个不同的文件使用相同的URL

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

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

我倾向于我的第二个想法,它不会有很大的效率,但最大的性能缺陷是在需要向数据库添加内容(测试冲突)时产生的,对于最终用户来说,这只发生一次。另一个性能缺陷可能是字符的实际外观而不是整数。但我主要担心的是这是一种坏习惯

编辑:


一个简单的解决方案是直接使用自动递增的值。你可以说我挑剔,但这看起来有点难看。

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

<?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."'");

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

<?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."'");

生成非冲突的短散列确实是一件令人头痛的事情。因此,Stackoverflow的slug格式非常有前途,并且保证生成不重复的url

例如,同样的问题也存在

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

在这里,它有唯一的主键,也有一个标题,使它更SE友好


然而,正如评论所说,他们是以前很少被问到的问题,这可能会弄清楚,为什么?你们正在尝试的是更好的遗漏


  • 创建短散列会大大增加冲突的机会,因此更好的用户
    base64
    sha512
    函数可以创建一个安全的散列。

    生成非冲突的短散列确实是一件令人头痛的事。因此,Stackoverflow的slug格式非常有前途,并保证生成不重复的url

    例如,同样的问题也存在

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

    在这里,它有唯一的主键,也有一个标题,使它更SE友好


    然而,正如评论所说,他们是以前很少被问到的问题,这可能会弄清楚,为什么?你们正在尝试的是更好的遗漏


  • 创建短哈希会大大增加冲突的可能性,因此更好的用户
    base64
    sha512
    函数可以创建安全哈希。

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

     SELECT BASE64_ENCODE(CAST(RAND()*1000000 AS UNSIGNED INTEGER)) AS tag
    
    这可以为您提供一百万个不同的标记。若要获得更多可能的标记,请增加RAND()数乘以的值。这些标记值将很难预测

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

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

    BASE64_ENCODE来自需要安装的存储函数。您可以在此处找到它:


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

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

     SELECT BASE64_ENCODE(CAST(RAND()*1000000 AS UNSIGNED INTEGER)) AS tag
    
    这可以为您提供一百万个不同的标记。若要获得更多可能的标记,请增加RAND()数乘以的值。这些标记值将很难预测

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

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

    BASE64_ENCODE来自需要安装的存储函数。您可以在此处找到它:


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

    我想做一些类似的事情(但要写文章,而不是上传文档),并想出了一些不同的方法:

    • 取一个素数[y](远大于文档的最大数量[n])(例如25000将足以容纳文档的总数,1000099是比250001大得多的素数)
    • 对于当前文档id[x]:(x*y)模块