1

/v=xxxYouTubeの見た目と動作に似たURLを作成しようとしています。つまり、ユーザーはファイルをアップロードし、そのURLを介してファイルにアクセスできるようになります。このURLコードは、ページが必要なデータを収集できるように、データベースの主キーの形式である必要があります。私はデータベースに不慣れであり、これは何よりもデータベースの問題です。

私のデータベースには、ファイルデータにアクセスするための自動インクリメント主キーがあります。その番号を使用してファイルのURLを作成したいと思います。さまざまなハッシュ関数を調べ始めましたが、衝突が心配です。2つの異なるファイルに同じURLは必要ありません。

uniqid()また、主キーとして使用することを検討しCHAR(13)、それを直接使用します。でもこれで効率が気になります。また、周りを見回すとあまり気付かないようですので、おかしな考えかもしれません。言うまでもなく、非効率になる可能性のあるIDが生成されたときに衝突をテストする必要があります。自動インクリメントははるかに簡単です。

これに対する良い解決策はありますか?私のアイデアのどちらかが機能しますか?自動インクリメントされた主キーから一意のURLを生成し、衝突を回避するにはどうすればよいですか?

私は2番目のアイデアに傾倒しています。これはあまり効率的ではありませんが、パフォーマンスの最大の欠点は、データベースに追加する必要がある場合(衝突のテスト)に発生します。これは、エンドユーザーにとっては1回だけです。他のパフォーマンスの欠点は、おそらくintではなくcharの実際の外観にあります。しかし、私は主にそれが悪い習慣であると心配しています。

編集:

簡単な解決策は、自動インクリメントされた値を直接使用することです。私をうるさいと呼んでください、しかしそれはちょっと醜いように見えます。

4

4 に答える 4

1

衝突しない短いハッシュを生成することは確かに頭痛の種になります。したがって、代わりにStackoverflowのスラッグ形式は非常に有望であり、重複しないURLを生成することが保証されています。

たとえば、これとまったく同じ質問があります

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

ここでは、一意の主キーと、SEをより使いやすくするためのタイトルがあります。


しかし、コメントされているように、彼らは以前に尋ねられた質問はほとんどありません、それは明らかになるかもしれません、なぜですか?あなたがしようとしていることは、省略したほうがよいでしょう。

  1. URLの一意のハッシュを生成するにはどうすればよいですか?
  2. Tinyurlスタイルのハッシュを作成する

短いハッシュを作成すると、衝突の可能性が大幅に高まるため、安全なハッシュを作成するためのユーザーbase64または関数が向上します。sha512

于 2012-08-16T16:54:21.987 に答える
0

単純に時間のハッシュを作成し、後でそのハッシュ(またはDB内のそのハッシュの一部。DB内のそのフィールドにインデックスを設定する場合)をチェックできます(ハッシュが十分に長く、多くを作成しないことを確認してください)衝突の)、それは常に問題になることはありません。

<?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."'");
于 2012-08-16T16:47:42.007 に答える
0

乱数を使用して短縮URLを生成する場合、これはかなり簡単です。たとえば、次のように実行できます。

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

これにより、100万の異なるタグを付けることができます。より多くの可能なタグを取得するには、RAND()数に乗算される値を増やします。これらのタグ値を予測するのは困難です。

重複が発生しないようにするには、タグ値を重複排除する必要があります。これは簡単に実行できますが、プログラムにロジックが必要になります。タグ値を主キーとして使用するテーブルに挿入します。挿入が失敗した場合は、RAND()を再度呼び出して再試行してください。

タグの最大数に近づくと、多くの挿入の失敗(タグの衝突)が発生し始めます。

BASE64_ENCODEは、イン​​ストールする必要のあるストアド関数から取得されます。あなたはここでそれを見つけることができます:

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

MySQL 5.6以降を使用している場合は、組み込みのTO_BASE64関数を使用できます。

于 2012-08-16T17:00:29.197 に答える
0

私は似たようなことをしたかったのですが(ただし、アップロードされたドキュメントではなく、記事を使って)、少し違うことを思いつきました:

  • これまでに存在するドキュメントの最大数[n]よりも(はるかに)大きい素数[y]を取ります(たとえば、25000はドキュメントの総数に対して十分な大きさであり、1000099は25001よりもはるかに大きい素数です)
  • 現在のドキュメントID[x]の場合:(x * y)モジュラス(n + 1)
  • これにより、重複することのない1からnまでの数値が生成されます

URLは従来の主キーのように見えるかもしれませんが、後続の各ドキュメントが前のドキュメントとはまったく関係のないIDを持つというわずかな利点があります。また、主キーを含めないことには、セキュリティ上の利点がごくわずかであると主張する人もいます...

于 2012-08-16T17:22:50.237 に答える