スレッド表示 | フラット表示〕 全トピック 920 件中 724 番目 次≫ ≪前

uniqid関数について

created: 2003-11-25 19:07 | modified: 2003-11-26 00:38 | reply: 6

[1084] uniqid関数について

user: akuro | created: 2003-11-25 19:07
こんばんは、akuroと申します。

uniqidを使って、IDを生成したいのですが、
この関数はマイクロタイムも同じ場合、
同じIDが生成されてしまうと言う事でしょうか?

マニュアルを見てみると、
「全く同じミリ秒のIDが生成されるのを防ぐの にprefixが有用です。」
とありました。

つまり、prefixに何らかの値を入れれば
絶対に重複はないという事でしょうか?
(id = uniqid(10);)

また、prefixを使用した場合、
最終的なidの桁数とかは制御
できないのでしょうか?


よろしくお願いします。
reply: 1085 返信 編集 削除

[1085] Re.uniqid関数について

user: ゆうじ | created: 2003-11-25 20:03
こんばんは。

> uniqidを使って、IDを生成したいのですが、
> この関数はマイクロタイムも同じ場合、
> 同じIDが生成されてしまうと言う事でしょうか?

以下のコードを実行したところ、
Hex文字の値が時間の経過と共に大きくなっているだけのようですので、
時間が同じならば、生成されるIDも同じでしょう。
<?php
// 同じ文字列を与えた場合
echo uniqid(""), "<br>";
echo uniqid(""), "<br>";
?>

> つまり、prefixに何らかの値を入れれば
> 絶対に重複はないという事でしょうか?
> (id = uniqid(10);)

prefix で指定した文字がはじめに付加されるだけのようですので、
同じ文字をprefix に与えれば異なってくるのは、
時間で生成されたID部分ということになりますね。
<?php
// 違う文字列を与えた場合
//echo uniqid("XYZ"), "<br>";
//echo uniqid("ABC"), "<br>";
?>

> また、prefixを使用した場合、
> 最終的なidの桁数とかは制御
> できないのでしょうか?

マニュアルには、prefix が空の場合、13桁とありますので、
prefix に与える桁数を制御すれば、
13桁?任意の桁のユニークなIDが生成できるのではないでしょうか。


# 以下はおせっかいです。
# 不要な情報の場合お許し下さい。

# 桁数が決まっている場合、
# この先ずっと絶対に重複しないユニークなIDを生成することは無理です。
# 絶対重複してはならない、
# 会員IDのようなものにこの使われるのでしたら、
# これまでに生成された会員IDと比較し、
# 重複があれば、重複しないIDが生成されるまで、
# 生成しなおす必要があります。
Parent: 1084  reply: 1086 返信 編集 削除

[1086] ReRe.uniqid関数について

user: akuro | created: 2003-11-25 21:08
akuroと申します、ゆうじさん返信ありがとうございます。

>prefix で指定した文字がはじめに付加さ
>れるだけのようですので、
>同じ文字をprefix に与えれば異なってく
>るのは、時間で生成されたID部分というこ
>とになりますね。

なるほど、ではprefixをさらにランダム
にする等の処理が必要ですね。

># 以下はおせっかいです。
># 不要な情報の場合お許し下さい。
いえ、情報ありがとうございます。

># 桁数が決まっている場合、
># この先ずっと絶対に重複しないユニーク
>なIDを生成することは無理です。
これは、いつか桁あふれしてしまう
ということになるからですよね。

># 絶対重複してはならない、
># 会員IDのようなものにこの使われるので
>したら、
まさにそのとおりでございます。
># これまでに生成された会員IDと比較し、
># 重複があれば、重複しないIDが生成され
>#るまで、生成しなおす必要があります。

最初、一意のIDを生成するのに、Postgresの
serialを使おうと思っていたのですが、
生成したIDをさらに使用して、他テーブルに
インサートする必要があるので一度
IDを取得しなければならなくなりました。
そこで、postgresのnextvalを用いて、
次のシリアル値を取得して使用しようかと
思ったのですが、その間に他で実行されると
最悪、IDのユニークを維持できないと判断し、
色々と検討している所でした。
(すみません、いきなり書いても内容が理解しがたいかと思いますが、、、)


さらに検討してみたのですが、
指定した桁数(予想申し込み数をカバーできる範囲)でランダム英数字を返す関数を作成し、ゆうじさんがご指摘していただいたように、一度そのIDが使用されているかを確認
するようにするかしたいと思うのですが、
この場合、重複チェックでIDに問題が
無いと判断された場合、
インサートする直前に、他のユーザーが
そのIDを使ってインサートを実行
してしまうなんてこともありえるでしょうか?
(確率的に、億に1回もないと思いますが、、、)

何度もすみませんが、よろしくお願いします。
Parent: 1085  reply: 1088 返信 編集 削除

[1088] Re.ReRe.uniqid関数について

user: ゆうじ | created: 2003-11-25 23:06
> 最初、一意のIDを生成するのに、Postgresの
> serialを使おうと思っていたのですが、
> 生成したIDをさらに使用して、他テーブルに
> インサートする必要があるので一度
> IDを取得しなければならなくなりました。
> そこで、postgresのnextvalを用いて、
> 次のシリアル値を取得して使用しようかと
> 思ったのですが、その間に他で実行されると
> 最悪、IDのユニークを維持できないと判断し、
> 色々と検討している所でした。
> (すみません、いきなり書いても内容が理解しがたいかと思いますが、、、)

それはそれは大変ですね。ご苦労お察しします。
php-users-ML に参考になりそうな記事を発見しました。
http://ns1.php.gr.jp/pipermail/php-users/2001-June/000033.html
こちらによると、サーバーの時計が狂いでもしない限り、
uniqid() のみでも相当に高い確率で
重複しないユニークIDが生成できるようです。


> さらに検討してみたのですが、
> 指定した桁数(予想申し込み数をカバーできる範囲)でランダム英数字を返す関数を作成し、ゆうじさんがご指摘していただいたように、一度そのIDが使用されているかを確認
> するようにするかしたいと思うのですが、
> この場合、重複チェックでIDに問題が
> 無いと判断された場合、
> インサートする直前に、他のユーザーが
> そのIDを使ってインサートを実行
> してしまうなんてこともありえるでしょうか?
> (確率的に、億に1回もないと思いますが、、、)

まったくないとは言い切れませんので
これも、「ある」ことを想定しておくべきでしょうね。

postgres を使ったことが無いのでわからないのですが、
テーブルのロック機能などを利用して、
キュー(処理待ち列)をつくるのが良いのだと思います。

キューの実現方法については、
私の知恵の及ぶ範囲を越えてますので・・・。
中途半端ですみません。
Parent: 1086  reply: 1090 返信 編集 削除

[1090] Re.Re.ReRe.uniqid関数について

user: akuro | created: 2003-11-25 23:48
返信ありがとうございます。

>php-users-ML に参考になりそうな記事を
>発見しました。
http://ns1.php.gr.jp/pipermail/php-users/2001-June/000033.html
>こちらによると、サーバーの時計が狂いで
>もしない限り、uniqid() のみでも相当に
>高い確率で重複しないユニークIDが生成で
>きるようです。

早速参照してみました。
そこで、内容がよく理解できなかったのですが、
「1日に8億以上のユニー
クIDを消費する限り、桁数はある程度以下には絞れないでしょうね。

とあったのですが、この8億ってどいう
意味で記述されたか分かりますでしょうか?
(IDが増えれば、それだけ桁数が増えるのは
しかたないという意味?)

他の記事についてここでお聞きするのは
場違いかもしれませんが、可能でしたら
よろしくお願いします。
Parent: 1088  reply: 1091 返信 編集 削除

[1091] 単純に

user: hamaji | created: 2003-11-25 23:58
横から口をはさむようですいません。
http://ns1.php.gr.jp/pipermail/php-users/2001-June/000033.html
より抜粋。
・・・
ミリ秒単位でユニークであることを保証する、つまり、1日に8億以上のユニー
クIDを消費する限り、桁数はある程度以下には絞れないでしょうね。
・・・
ここまで

単純に一日をミリ秒に直したら8億ミリ秒強ということだと思います。
1日 = 3,600秒(1時間)×24 = 86,400秒
86,400 × 10の3乗(ミリ秒) = 864,000,000ミリ秒
で約8億ミリ秒。以上
Parent: 1090  reply: 1092 返信 編集 削除

[1092] Re単純に

user: akuro | created: 2003-11-26 00:38
akuroと申しますhamajiさん返信ありがとうございます。

>単純に一日をミリ秒に直したら8億ミリ秒強ということだと思います。

なるほど、そういうことでしたか。
ありがとうございました。
Parent: 1091  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 724 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑