- - PR -
ユニークなIDの自動生成
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-09-06 10:30
MySQL5で
t1というテーブルのフィールドが +-------+-------------+ | Field | Type | +-------+-------------+ | id | int(11) | | name | varchar(10) | +-------+-------------+ のような構成で、IDが主キーとして テーブルデータが +----+------+ | id | name | +----+------+ | 1 | a | | 2 | b | | 3 | c | | 4 | d | +----+------+ となっているときに、idが2番の行を削除してから insert into t1 (name)values('z'); を実行したときに +----+------+ | id | name | +----+------+ | 1 | a | | 2 | z | | 3 | c | | 4 | d | +----+------+ と新しいIDが抜けた隙間になるようにIDを自動生成 したいのですがそういった事は可能でしょうか? auto_increment属性だと、 +----+------+ | id | name | +----+------+ | 1 | a | | 3 | c | | 4 | d | | 5 | z | +----+------+ になってしまいます。 auto_increment値を0にリセットしたらできるかなと思ったのですが 駄目でした。 どなたか良い方法をしっておられる方はおられないでしょうか? そんなん無理だよという意見でも、無理だとわかる時点で あきらめが着くので助かります。 よろしくお願いします。 [ メッセージ編集済み 編集者: ひろ 編集日時 2007-09-06 10:32 ] | ||||||||
|
投稿日時: 2007-09-06 11:12
手間はかかりますが、IDを最初からなめていって空きがみつかった時点でそのIDを新IDにする手動検索のような感じでしょうか?
あとは削除するときに削除IDをどこかに記録しておくとか? 自動的に空きを埋める機能は知ってる限りではないと思いますが、追加されてたりするのかも?しれません。 その辺は他の人からのレスを待ちます。 | ||||||||
|
投稿日時: 2007-09-06 11:58
そういうIDをselect(とかそういうIDにinsert)するSQLを書くことはできますよ。
ただしこれの問題点は | 3 | a | | 4 | z | | 6 | c | | 7 | d | のような場合「5」が空きIDとして返されます。 (この方法でselectした値と「1」のうち小さい方、とすればいいだけですけどね) #MIN(TABLE.ID+1)をMIN(t1.ID+1)に修正 #ORDER BY t1.ID を削除 ・・昔ブログにかいたやつなのに、、間違い多いwwww [ メッセージ編集済み 編集者: べる 編集日時 2007-09-06 12:24 ] | ||||||||
|
投稿日時: 2007-09-06 13:15
すいません。質問させて下さい。
t1はもとのテーブルとしてt2はどこから出てきたのでしょうか? 上記SQL文を実行してみましたがエラーが返ってきます。 色々と調べて上記SQL文をなんとか読解しようとはしているのですが なにぶんSQLの初心者なもので・・・ | ||||||||
|
投稿日時: 2007-09-06 13:44
ごめんなさいTABLEという名前(しかもt1もかぶって、、)がよくなかったですね。
ひろさんの最初の例でいうとこうなるでしょうか。
table1もtable2も元は同じt1テーブルです。自己結合とか呼ばれたりします。 | ||||||||
|
投稿日時: 2007-09-06 13:57
できました!
これで解決しそうです。 table1とtable2は一時的にt1をコピーしたものなんですね。 自己結合ですか。色々便利そうなので勉強してみます。 ありがとうございました。 | ||||||||
|
投稿日時: 2007-09-06 14:19
いや「t1 AS table1」「t1 AS table2」などをコピーと呼んでは間違いの元だと思うので、正しく理解しておいてください。けっしてt1をコピーしてtable1,table2を作成しているわけではないので・・。 | ||||||||
|
投稿日時: 2007-09-06 15:03
IDを自分で採番するときは、トランザクションに気をつけた方が良いですよ。
同時に実行して、同じIDが取得されたら目が当てられません。 採番用の関数を作って中でダーティーリードした方が良いと思います。 素直にauto_incrementが安全だと思いますよ。 ※追記 あと、デッドロックも気になります。 [ メッセージ編集済み 編集者: よっしー 編集日時 2007-09-06 15:05 ] |