- - PR -
唯一のキー(ID)を作成する方法について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 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が複数あった場合でも、読み込むクラスのディレクトリをマウントなどで、 共通にしておけば、唯一のハッシュコードを取得可能なのでしょうか? 以上、よろしくお願いします。 | ||||||||
|
投稿日時: 2006-01-02 13:05
J2SE 5.0ならUUIDってクラスがありますよ。
| ||||||||
|
投稿日時: 2006-01-02 13:14
まず、「ミリ秒」と「ハッシュコード」を組み合わせることが、そもそも無意味です。たしかに、バッティングの確率を減らすことにはつながるかもしれませんが、でもゼロではありません。確率がゼロでないからには、それに対応する処理を備えなければなりませんから(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)キーであり、このような人為キーを使うがゆえの問題ですので、既存のキーでやりとりできれば、このようなことを気にする必要がなくなりますので、もし可能ならばそうしたほうがよいです。 | ||||||||
|
投稿日時: 2006-01-02 13:24
返信ありがとうございます。
>J2SE 5.0ならUUIDってクラスがありますよ。 現在使用しているシステムは、J2SE1.4なので、UUIDは使用できません。 ですが、今後の参考にしたいと思います。 ありがとうございます。 >ただ、「ミリ秒+DAOのハッシュコード」にしろ GUID にしろ、これらは人為(人工, >artificial)キーであり、このような人為キーを使うがゆえの問題ですので、既存のキー>でやりとりできれば、このようなことを気にする必要がなくなりますので、もし可能な>らばそうしたほうがよいです。 詳細な返信ありがとうございます。 「ミリ秒+DAOのハッシュコード」では、100%ユニークになるわけではないのですね。 ただ、 >既存のキーでやりとりできれば というのは、どのキーのことでしょうか? DBのAuto_incrementなどのことでしょうか? よろしくおねがいします。 | ||||||||
|
投稿日時: 2006-01-02 18:31
単純に キー取得テーブルから値を取得してその値を+1して使ってます。
今の所不具合は無いです。 | ||||||||
|
投稿日時: 2006-01-03 18:30
返信ありがとうございます。
単純に、既存のキー+1でも問題なさそうですが、 JVMが2台以上で稼動している場合、シリアライズなどを用いても、 同時に書き込みが行われた場合、値が保障されないような気がするのですが、 いかがでしょうか? | ||||||||
|
投稿日時: 2006-01-03 21:40
いいえ、そうではないです。たとえば、顧客テーブルに、名前カラムと住所カラムがあったら、それを組み合わせて主キーとして使えれば、それを使う、ということです。もっとも、こうするためには、同姓同名の人が同居していない、などという条件が必要なので、こういうことを考えるのは面倒です。人為キーを使えばこういうことは一切考える必要がないので楽ですが、逆に、人為キーをどう生成すべきか、で悩むわけです。
JVM とは別に、DBMS にも(トランザクションの)シリアライゼーションの仕組みがありますので、トランザクションを正しく使えば重複することはありません。 もっともこれは「Auto_Increment」と大きな違いはありません。「Auto_Increment」は DBMS に備わっている機能なので使うのは楽ですけど。 | ||||||||
|
投稿日時: 2006-01-03 23:44
返信ありがとうございます。
なるほど。 既存のその他のキーを複数しようすることにより、 ユニークにできるということですね。 確かにそのとおりです。 また、DBMSにもシリアライゼーションの仕組みがあることは知りませんでした。 現在は、Auto_Incrementを使用していますので、特に問題はなさそうですが、 気になっていたことが解決いたしました。 ありがとうございました。 |