[PHP-users 11278] Re: PHP+MySQL連番について

Naofumi Kondoh php-users@php.gr.jp
Tue, 05 Nov 2002 17:15:08 +0900


ソフト工房の近藤です。

tonnnura@anet.ne.jp wrote:
> 大変お世話になっております。SAITO TAKAです。
> 
> MySQLで、
> auto_increment primary key
> 自動で連続する番号を振るフィールドを作ろうしています。
> しかし、MySQLの仕様で、
> 空きがある番号も飛ばして最大の番号を振ってしまいます。
> 
> --------------------------------
> 1 2 3 4 5 6 9 10
> のときは、
> 11 が振られてしまいます。
> --------------------------------
> 
> これを、PostgreSQLのように、
> 
> --------------------------------
> 1 2 3 4 5 6 9 10
> のときは、
> 7 が振られる。
> --------------------------------
> 
> というようにしたいのですが、

MySQL は知らないのですが、PostgreSQL について
誤解されているところがあるので、先ずそこから。

PostgreSQL の連番型( SERIAL )は、生成された SEQUENCE名
ごとに単純に連続番号を返すだけです。Informix DB のように、
使用する表で UNIQ であるという保証はありません。

例えば、CREATE SEQUENCE test_id_seq start 1 ; の場合、
1 2 3 4 5 6 と連番を発生させるだけです。もしこの時に、
SEQUENCE を使用しないで、9, 10 の2つの UNIQ KEY を INSERT
したとすると、SEQUENCE は、7 8 9 10 11 と連番を発生させ
ますので、9 10 の2つが、DUPE KEY ERROR となって、INSERT
できなくなります。

このため、PostgreSQL の SEQUENCE を利用した表で、SEQUENCE
以外の方法で INSERT した場合(例えば外部データーの import)
は、必ず、下記のような SQL コマンドで、SEQUNECE の発生番号
を訂正しないと重複キーが発生する可能性があります。

 select setval('"test_id_seq"', (select max(test_id) from test));

---------------

TAKA さんがご要求の欠番のない連番に近いものが必要となる
例はあまり思いつかないのですが、具体的にどのような用途で
しょうか?。

私が経験した例では、あらかじめ連番を刻印した商品とか会員証
などがあって、かつ、特定の希望者には、任意の空き番号を指定
でき、そうでない人には、空き番号の中の最小のものから自動で
番号を振るというような用途がありました。しかも、自動で番号
を振った場合も、申込み時点で番号はとるのですが、会員証や
商品引き渡し前にキャンセルがあると、その番号を再利用する
(つまり、番号刻印済みの商品を無駄にしない)というものでした。
特種な例だと思います。

この例では、仕方ないので、空き番号のはいった表を作成して、
自動採番するときは、最小値を SELECT MIN(idnum) FROM xxxx;
してから DELETE。キャンセルした時は、その番号を空き番号表
に INSERT するという方法をとりました。、

このような特種な用途かどうかわかりませんが、ご参考までに。

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 (株)ソフト工房   近藤直文        Email:  nkon@shonan.ne.jp
http://www.SOFTKOUBOU.co.jp/      http://www.shonan.ne.jp/~nkon/
2002-11-28(木)19:00-21:30 第8回 JPUG 業務アプリ分科会 勉強会
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/