AUTO_INCREMENTを使わずにシーケンスをエミュレートする
冗長化を考えるとAUTO_INCREMENTなカラムってちょっと使いにくかったり…。 あるいはトランザクションセーフな処理を考えて見ても、AUTO_INCREMENTを使うと、 INSERTしてからlast_insert_idで取得って流れになってしまい、やっぱり使いにくいなぁなんて。
余り知られていないかもしれないが、公式ドキュメントでも紹介しているシーケンスのエミュレート方法についてメモって見ます。
どのようにやるかと言えばシーケンスをエミュレートするテーブルを作り、 その中でシーケンスの値を保持する唯一つのレコードがあればOKです。
CREATE TABLE Sequences
(
member_seq bigint not null default 1,
friend_seq bigint not null default 0
)
TYPE = InnoDB;
INSERT INTO Sequences(member_seq, friend_seq) VALUES(0, 0);
このテーブルと一つ追加したレコードに対して、次のように遊んでみる。
mysql> UPDATE Sequences SET member_seq = last_insert_id(member_seq) + 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT @next_member_seq := last_insert_id(member_seq) FROM Sequences;
+------------------------------------------------+
| @next_member_seq := last_insert_id(member_seq) |
+------------------------------------------------+
| 1 |
+------------------------------------------------+
1 row in set (0.00 sec)
こうすれば@next_member_seqで同一トランザクション内で上手くシーケンスを使えそうだなと。 これSELECT-INSERTを使うとユーザー変数使わないでも出来ます。
コメント
なるほどー。相変わらず勉強熱心でつね (*'v')b
投稿者: amachang | 2006年06月19日 16:18
AUTO_INCREMENTって楽チンなんですが、
Oracleのようにシーケンステーブルがほしい場合もありますね。
投稿者: nekokak | 2006年06月21日 09:40
> amachang
日々勉強あるのみですよ。
> nekokakさん
そうなんですよね、シーケンスが欲しいシーンってやっぱりあるんですよねぇ。
MySQL 5.1から対応だったような気がしたような…。
投稿者: ZIGOROゥ | 2006年06月21日 20:25
NQESvj hi good site thx http://peace.com see you
投稿者: bob | 2007年11月17日 05:18