【MySQL+PHP】AUTO_INCREMENTの次回値を取得する方法
お久しぶりです。
試験期間で長らく更新が止まっていました。
まぁいつものことなんですが。
さて、今回はMySQLのお話。
MySQLにはAUTO_INCREMENTという便利な属性があります。
AUTO_INCREMENT属性は以下の様な特徴があります。
・数値を挿入することができる
・値を挿入する際に自動的に値がインクリメントされる
・(つまり、連番データの作成が楽になる!)
このAUTO_INCREMENT属性はPRIMARY KEYと組み合わせることが多いです。
PRIMARY KEYを設定しておくことで、カラム内に同じデータが存在してしまうことを防げます。
連番かつ一意のデータ、つまりIDですね。
ユーザーを識別するために、アプリケーション内部で利用されるIDなどの割り振りに便利です。
PRIMARY KEYにより重複することもありませんし、ID番号を明示しなくても自動的に連番データが与えられます。
で、ここから本題。
このAUTO_INCREMENTの次回値を取得しましょう。
例えば、あるIDと同じように、連番でファイル名を命名したい場合など。
「ID:01に対し、File01.datを与える。ID:02に対し、File02.datを与える…」
こんなかんじで、IDとファイル名を対応させたい場合のことを考えましょう。
現在の値を取得することは比較的容易です。クエリ文ひとつで済みます。
しかし、次回値が「現在値+1」とは限らない場合もあります。
「ID:12とID:13が登録され、後にID:13が削除された」と考えてみましょう。
この場合、次回値は14となり、「現在値12+1」ではありません。
このような事態は、次回値を取得できれば避ける事ができます。
では、実際に試してみましょう。
実行したいクエリ文は以下のとおり。
1 |
CREATE TABLE sample_tbl(id int primary key auto_increment, name text);
|
このクエリ文で以下のカラムが作成されます。
id(int):primary key, auto_increment
name(text):
では、auto_incrementの次回値を参照してみましょう。
実行するべきクエリ文は以下です。
1 |
SHOW TABLE STATUS LIKE 'sample_tbl';
|
このクエリ文を実行することで、テーブルのステータスを確認することが出来ます。
このステータスには、照合順序や作成日時などが含まれ、auto_incrementの次回値も入っています。
ステータスが取得出来れば、あとはデータをパースしてauto_incrementの値を拾ってくれば終わりです。
たったこれだけのことなのですが、MySQL初心者には結構難しいです。
私も気づくまでに結構苦労しました。
簡単なので、むしろ情報がないのだと思います。
もし同じ問題で悩んでいる方は、上記の方法で解決してみるといいかもしれません。
さて、上でやったのはあくまでも、「取得」しただけです、実際に利用してみましょう。
PHPで書いていきます。
[テーブル作成]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php
$query = 'create table sample_tbl(id int primary key auto_increment, name text);';
$link = mysql_connect('localhost', 'usr', 'pssword');
if (!$link) {
echo('error. Connect Faild.');
exit(1);
}
$db_selected = mysql_select_db('test_db', $link);
if (!$db_selected){
echo('error. Select DB Faild.');
exit(1);
}
$result = mysql_query($query);
if (!$result) {
echo('error. Query_error;');
exit(1);
}
?>
|
[AUTO_INCREMENT次回値取得と表示]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<?php
$link = mysql_connect('localhost', 'usr', 'password');
if (!$link) {
echo('error. Connect Faild.');
exit(1);
}
$db_selected = mysql_select_db('test_db', $link);
if (!$db_selected){
echo('error. Select DB Faild.');
exit(1);
}
$query = "SHOW TABLE STATUS LIKE 'sample_tbl'";
$result = mysql_query($query);
if (!$result) {
echo('error. Query_error.');
exit(1);
}
//$rowへのデータ格納
$row = mysql_fetch_object($result);
//next_idにAuto_incrementの値を代入
$next_id = $row->Auto_increment;
mysql_free_result($result);
mysql_close($link);
echo($next_id);
?>
|
22行目:受けっとたデータをmysql_fetch_object()で$rowに格納
23行目:22行目で格納されたオブジェクトの、Auto_incrementが次回値のとなる
こんな感じで、簡単に取得できました。
あとは適当にファイル名に使うなり、色々使い道はあると思います。
今回はこんな感じかなー。
MySQL初心者の備忘録みたいなものですので、役に立つかわかりませんが、参考にでもなれば幸いです。
k0y
2013年6月30日 - 11:59 PM
アプリケーションで複数のクライアント(WEBサーバなど)で使う場合、
auto_incrementの値が更新される可能性があるので、
トランザクション内で insert なりしてその値を
取ったほうがいいと思います。
# 最終的に insert が不要になったら rollback
かまぼこ
2013年7月2日 - 11:51 PM
ご意見ありがとうございます。
ご指摘の通り、複数のクライアントがある場合はauto_incrementの値が更新されてしまう可能性があります。
特にPHPと絡ませるということは、用途はほぼウェブに限られてきますし。
rollbackというものがあるのですね。知りませんでした。
最初はinsertした結果から取ってくることも考えていました。
insertが不要になった場合の削除処理をしなければならないと思っていましたが、rollbackを使えば簡単に実装できそうですね。
データの整合性も保たれて、安心ですね。
ご指摘ありがとうございます。今後の参考にさせていただきます!
Stew Eucen
2015年9月11日 - 5:59 AM
かまぼこさん、初めまして。通りすがりの DB エンジニアです。
insert してから auto_increment された値を取得して、不要な場合は rollback する処理についての補足です。
現時点でテーブルに入ってる最大の ID が 100 で、次の auto_increment の値が 101 とします。この状況でinsert ~ rollback すると、auto_increment の値は 102 に進み、次に insert した時の ID は 101 ではなく 102 になります。rollback しても auto_increment は元に戻らず、ID の数値が消費されます。
ID の役割では飛び番号があっても問題はありません。また、int 型で 21億レコードまで対応できるため、多少浪費したとしても超大規模なサイトでもない限り実用性に影響が出ることはないでしょう。
insert からの rollback で auto_increment の附番が浪費される、という挙動を知っておくのは無駄ではないかと思います。