- PR -

唯一のキー(ID)を作成する方法について

投稿者投稿内容
Masayuki2501
常連さん
会議室デビュー日: 2006/01/02
投稿数: 25
投稿日時: 2006-01-02 11:48
こんにちは。

現在、Webアプリを作成していますが、DB(MySQL)にIDを作成する必要があります。
このIDを用いて、いくつかのテーブルを結合して、DBからデータを取得させています。

今作成しているシステムでは、DBのAuto_Incrementを使用していますが、
これ以外の方法として、DBに書き込む際にのミリ秒+DAOのハッシュコードでも
代用できるのではないかと考えています。
(DAOはDBに書き込む共通のクラスです。)

ミリ秒の取得は、CalendarクラスのgetTimeInMillisを使用し、
ハッシュコードは、this.hashCode()を使用使用と考えています。

この場合、JVMが複数あってもDAOのハッシュコードは異なるのでしょうか?
単一のJVMで動作しているときにのみ、使える手法なのでしょうか?

また、JVMが複数あった場合でも、読み込むクラスのディレクトリをマウントなどで、
共通にしておけば、唯一のハッシュコードを取得可能なのでしょうか?

以上、よろしくお願いします。



Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-01-02 13:05
J2SE 5.0ならUUIDってクラスがありますよ。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-01-02 13:14
引用:

Masayuki2501さんの書き込み (2006-01-02 11:48) より:
今作成しているシステムでは、DBのAuto_Incrementを使用していますが、
これ以外の方法として、DBに書き込む際にのミリ秒+DAOのハッシュコードでも
代用できるのではないかと考えています。
(DAOはDBに書き込む共通のクラスです。)


まず、「ミリ秒」と「ハッシュコード」を組み合わせることが、そもそも無意味です。たしかに、バッティングの確率を減らすことにはつながるかもしれませんが、でもゼロではありません。確率がゼロでないからには、それに対応する処理を備えなければなりませんから(Hashtable や HashSet/HashMap などのチェーン処理等のように)。

また hashCode だけに限って言えば、
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/Object.html#hashCode()
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#hashCode()
のように「できるかぎり、Object クラスで定義される hashCode メソッドは、異なるオブジェクトについては異なる整数値を返します。」とあるように、「できるかぎり」異なる値は返してくれますが、所詮、「できるかぎり」です。同一の VM ですでにそうなのですから、違う VM であってもユニークなことを期待しないほうが良いでしょう(VM の実装に依存してしまいます)。

ちなみに、Microsoft Access (Jet) だと、キーに GUID を使うこともできるみたいです。GUID の概念自体は、DBMS によらないと思いますし、Windows なら API で GUID を生成することもできるので、GUID を使うほうがまだ良いと思います。

ただ、「ミリ秒+DAOのハッシュコード」にしろ GUID にしろ、これらは人為(人工, artificial)キーであり、このような人為キーを使うがゆえの問題ですので、既存のキーでやりとりできれば、このようなことを気にする必要がなくなりますので、もし可能ならばそうしたほうがよいです。
Masayuki2501
常連さん
会議室デビュー日: 2006/01/02
投稿数: 25
投稿日時: 2006-01-02 13:24
返信ありがとうございます。

>J2SE 5.0ならUUIDってクラスがありますよ。

現在使用しているシステムは、J2SE1.4なので、UUIDは使用できません。
ですが、今後の参考にしたいと思います。
ありがとうございます。

>ただ、「ミリ秒+DAOのハッシュコード」にしろ GUID にしろ、これらは人為(人工, >artificial)キーであり、このような人為キーを使うがゆえの問題ですので、既存のキー>でやりとりできれば、このようなことを気にする必要がなくなりますので、もし可能な>らばそうしたほうがよいです。

詳細な返信ありがとうございます。
「ミリ秒+DAOのハッシュコード」では、100%ユニークになるわけではないのですね。

ただ、
>既存のキーでやりとりできれば

というのは、どのキーのことでしょうか?
DBのAuto_incrementなどのことでしょうか?

よろしくおねがいします。
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2006-01-02 18:31
単純に キー取得テーブルから値を取得してその値を+1して使ってます。
今の所不具合は無いです。
Masayuki2501
常連さん
会議室デビュー日: 2006/01/02
投稿数: 25
投稿日時: 2006-01-03 18:30
返信ありがとうございます。

単純に、既存のキー+1でも問題なさそうですが、
JVMが2台以上で稼動している場合、シリアライズなどを用いても、
同時に書き込みが行われた場合、値が保障されないような気がするのですが、
いかがでしょうか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-01-03 21:40
引用:

Masayuki2501さんの書き込み (2006-01-02 13:24) より:
ただ、
>既存のキーでやりとりできれば

というのは、どのキーのことでしょうか?
DBのAuto_incrementなどのことでしょうか?


いいえ、そうではないです。たとえば、顧客テーブルに、名前カラムと住所カラムがあったら、それを組み合わせて主キーとして使えれば、それを使う、ということです。もっとも、こうするためには、同姓同名の人が同居していない、などという条件が必要なので、こういうことを考えるのは面倒です。人為キーを使えばこういうことは一切考える必要がないので楽ですが、逆に、人為キーをどう生成すべきか、で悩むわけです。

引用:

Masayuki2501さんの書き込み (2006-01-03 18:30) より:
単純に、既存のキー+1でも問題なさそうですが、
JVMが2台以上で稼動している場合、シリアライズなどを用いても、
同時に書き込みが行われた場合、値が保障されないような気がするのですが、
いかがでしょうか?


JVM とは別に、DBMS にも(トランザクションの)シリアライゼーションの仕組みがありますので、トランザクションを正しく使えば重複することはありません。
もっともこれは「Auto_Increment」と大きな違いはありません。「Auto_Increment」は DBMS に備わっている機能なので使うのは楽ですけど。
Masayuki2501
常連さん
会議室デビュー日: 2006/01/02
投稿数: 25
投稿日時: 2006-01-03 23:44
返信ありがとうございます。

なるほど。
既存のその他のキーを複数しようすることにより、
ユニークにできるということですね。
確かにそのとおりです。

また、DBMSにもシリアライゼーションの仕組みがあることは知りませんでした。
現在は、Auto_Incrementを使用していますので、特に問題はなさそうですが、
気になっていたことが解決いたしました。
ありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)