2010年10月7日木曜日

MySQLのオートナンバーについてコメントがありました。

昨日MySQLでオートナンバーはないのかとつぶやいたら以下のようなコメントがありました。

或間二郎 さんは書きました...

>MySQLにはオートナンバーってなかったですかね

だいじょうぶ、ちゃんとあるよ。
さしあたっては、
http://dev.mysql.com/doc/refman/5.1-olh/ja/numeric-type-overview.html
とか
http://www.dbonline.jp/mysql/table/index7.html
を参照して下さい。

MySQL の話題が出たので嬉しくなって書き込んでしまいました。(^。^;
さっそくhttp://dev.mysql.com/doc/refman/5.1-olh/ja/numeric-type-overview.htmlを辿ってみましたが、なんとも難しくて歯がたちません。っていうか、どうすればオートナンバーになるのかさっぱりわかりません。これでまたハゲが進行してしまった。2番目のリンクhttp://www.dbonline.jp/mysql/table/index7.htmlにはなぜか辿り着けませんでした。

ここまで書いて、もしかして、「MySQL オートナンバー」で検索したら出てくるかも知れないと思い実行しましたら、ありましたね。やはり検索の仕方で結果がかなり違ってきますね。
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/php_s01.htm
■順序項目(オートナンバー)

・MySQL では、auto_increment と指定する。

create table test (
keyno auto_increment primary key,
data1 bigint,
data2 bigint,
data3 bigint
);

・PostgreSQL では、serial と指定する。

create table test (
keyno serial primary key,
data1 int8,
data2 int8,
data3 int8
);

他にも MySQL と PostgreSQL で少し細かな違いがあるようだが、ほぼ同一の
構文で SQL を発行できる。
データ型の一覧も出ていたので、ついでだから書いておこうっと。これからイチイチ調べるのもメンドイですからね。
■テーブル項目型(フィールド型)

・MySQL 項目型

int / integer 4 バイト整数
smailint 2 バイト整数
bigint 8 バイト整数
float 浮動小数点
double / real 倍精度浮動小数点
date 日付
time 時間
timestamp 日付時間
char(文字数) 固定長文字列 (最大 256 文字)
varchar(文字数) 可変長文字列 (最大 256 文字)
text ラージ文字列 (最大 65535 文字)
mediumtext ラージ文字列 (最大 1677215 文字)
largetext ラージ文字列 (最大 4294967295 文字)
blob ラージバイナリ(最大 65535 bytes)
mediumblob ラージバイナリ(最大 1677215 bytes)
largeblob ラージバイナリ(最大 4294967295 bytes)

・PostgreSQL 項目型

smailint / int2 2 バイト整数
integer / int / int4 4 バイト整数
bigint / int8 8 バイト整数
decimal(a, a) / numeric(a, s) 10 進型
real / float4 6 桁単精度浮動小数点
double precision / float8 15 桁倍精度浮動小数点
serial 4 バイト順序
bigserial 8 バイト順序
date 日付
time 時間
timestamp 日付時間
char(文字数) / character 固定長文字列 (最大 4096 文字)
varchar(文字数) / charcter varying 可変長文字列 (最大 4096 文字)
text 無制限テキスト
ラージオブジェクト oid 型 (いまいちわからん) (^^;
boolean / bool true / false


以下はついでというかおまけですね。http://www.mysql.gr.jp/mysqlml/mysql/msg/9277

はじめまして入江といいます。

もうスレッドが収束しそうなところへしゃしゃり出て申し訳ありません。

>auto_increment型について質問がありまして投稿しました。高橋と申します。

auto_increment型ですがこのように考えたらいかがでしょう。

※※主キーをコンピュータに任せるシステム※※

主キーの役割はご存知ですよね。

※行を特定するための列である。
※他の行と同じものがあってはならない。
※一度設定したら基本的には変更しない。

この特徴があるから他の表との関係を正常化することが出来ます。

当然その為には人が入力する値であれば同一のものが出てこないようにチェックをし
なければならない。

プログラムから生成する場合にも、過去に生成された値と重複しないように管理が必
要になります。

つまりこれを考えるだけで結構な工数が必要になりますよね。

「松枝」さんの言われているようにマルチタスクマルチユーザ環境であればさらにこ
れに衝突しないように同期を取っていかなければなりません。

(シングルとマルチではプログラムの仕方はまるっきり変わってきます。このあたり
は肌で感じるように経験を積んで下さい。)

ちょっと話がそれてしまいましたが、auto_increment型があればそれらを一切考えな
くても重複しない「主キー」値を生成してくれます。

先ほども言いましたが主キーには「データベースアプリケーションが行を特定する」
という意味を与えておけばいい事になります。

僕がシステムを設計する場合には主キーはこの意味以外を与えません。

年度が必要であれば年度列を設けます。連番が必要であれば連番列を設けます。

それが主キーでなければ後での調整もし易いはずです。

そして主キー列は表面には出しません。
(プログラム内、SQL内では使いますが人間の読む場所には出さないって事です)

Accessのオートナンバー型もMySQLのauto_increment型もかなりの人々が連番を付け
る為に利用されてしまいがちですが、数が自動的に増えていくのはあくまでも過去の
値と衝突しない一番簡単な方法をとっているに過ぎません。
(後は挿入順になってくれるってメリットもあるかもしれませんね)

当然auto_increment型は挿入しないとどんな値になるか分からないですよね。
他の表との関係をとっているときには致命傷になります。
ですからLAST_INSERT_ID()でMySQLにどんな値を入れたのか教えてもらう事になりま
す。

もう一度主キーの目的を考えてみて下さい。

それで失礼いたします。

--
Kenji Irie mailto:kenji@xxxxxxxxxx


primary keyのことをすっかり忘れていました。だから先日書き込みしたときに行を削除するとしましたが、実際は削除しないで、削除行にはマーク付けだけをしておくべきなのですよね。だんだんと思い出してきたな。ふむふむ
コメントを投稿