• 締切済み

テーブルの自動キー再割り当て

以下sqlでテーブルhogeを作成し、idを自動キーにしています。 CREATE TABLE `hoge` ( `id` INT NOT NULL AUTO_INCREMENT, ........(省略).......... PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=sjis; このテーブルのレコード番号4を削除するとテーブルのidは 1,2,3,5(最終)になり, 新しいデータを追加(INSERT)するとidは 1,2,3,5,6(最終)とid番号4が欠番になります。 テーブルのidを1,2,3,4,5と続き番号に再割り当てして、新しいレコードがid番号6の挿入されるようにするにはどのようにすればよいでしょうか? sql文をご教示い頂きたくよろしくお願いします。

  • MySQL
  • 回答数4
  • ありがとう数3

みんなの回答

回答No.4

失礼。勘違いしていました。「空きの番号を再利用」でなく、番号を連番で付け直したいと言っていたのですね。 #3で書いたLIMIT句ですが、次のような使い方をします。 SELECT * FROM t1 [WHERE 検索条件} ORDER BY id LIMIT m,n LIMIT m,nで、「m+1行目からn行を得る」という意味になります。

kahata
質問者

お礼

LIMITの有用な使い方をありがとうございます。 プログラミング(PHP)側でSELECTレコードセットのidを配列に取得する方法や次のレコードにseekする方法も考えましたがもう一つぴったりしませんでした。 なるほどLIMITを使えばsql側で色々応用が可能ですね。参考にさせて頂きます。ありがとうございました。

回答No.3

削除自体というよりは、番号を再利用することが前提なのに、削除するというのは非効率的です。他にもいろいろ理由はあるのですが、今回の質問と直接関係しないので省略します。 >色々試みましたが、結局以下のようにidを削除した後、再びidを追加して >連番を振り直しました。 >ご指摘のようにこれからは出来るだけレコードを削除しないようにしたい >と思います。 >ALTER TABLE `hoge` DROP `id`; >ALTER TABLE `hoge` ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT > PRIMARY KEY FIRST ; マニュアルにも明記されていますが、MySQLのALTER TABLEでの列追加は、全行のコピー(INSERT)が発生しますよ??? >この様な必要が生じたのはidをインクリメント(デクリメントして) >レコードを次々ページングする処理をしているため idの付け直しとかでなく、SELECT文でLIMIT句を使えば解決するような話しにも思えますが?

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

>DELETE文で削除するのはよく行われると思う そんなことはありません。 きちんとしたデータ管理をする場合は、削除というのはほとんど行いません。 削除したというフラグを立てておき、SELECTの際に表示しないというのが正しい やり方です。 それはデータの履歴性の問題です。 もちろん運用の仕方によっては削除することもおかしいとはいえません。 ただ「連番」という意味のないことのためにいちいち各データの 項目を書き換える=連番をつけなおすことは全うなやり方ではありません。 どうしてもやりたいなら連番専用の外部テーブルを作成しておき プライマリキーをもとに付け直す処理が必要になります。

kahata
質問者

お礼

コメントありがとうございます。 色々試みましたが、結局以下のようにidを削除した後、再びidを追加して連番を振り直しました。 この様な必要が生じたのはidをインクリメント(デクリメントして)レコードを次々ページングする処理をしているためです。 ご指摘のようにこれからは出来るだけレコードを削除しないようにしたいと思います。 ALTER TABLE `hoge` DROP `id`; ALTER TABLE `hoge` ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;

回答No.1

MySQLでのauto_incrementだけでは実装できないので、そういったSQLを作る必要があります。 MySQLのバージョンは、何でしょうか? MySQL 4.0以前、4.1、5.0以降かによって、実装方法が大きく違ってきます。 なお、削除したり、空いている番号を探すというのは、大きなオーバヘッドになりますよ?

kahata
質問者

補足

レスありがとうございます。 MySqlのバージョンはMySQL Server 5.0 (for Windows)です。 また次の意味がよくわかりません。DELETE文で削除するのはよく行われると思うのですが、時間がかかるという意味でしょうか? あわせて追加ご教示頂ければ幸いです。よろしくお願いします。 >なお、削除したり、空いている番号を探すというのは、大きなオーバヘッドになりますよ?

関連するQ&A

  • 空きのID番号を取得する方法

    いつもお世話になっております。 create table AAA( ID int(6) primary key not null auto_increment, DATA varchar(30), )engine=MyISAM; というテーブルにおいて、 insertをすると、IDが1から順に割り振られていきますが、 途中のレコードをdeleteすると、そこが空きのID番号となってしまい、 次にinsertすると、空き番号が残ってしまいます。 やりたいことは、その空き番号を有効活用するために、 auto_incrementを使用せずに、空き番号を適当に取得して、 insertをしたいのです。 何か効率的な良い方法をご存知の方がいらっしゃいましたら、 ご教授いただけると幸いです。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • auto_incrementを任意の数字から開始するには

    次のようなテーブルで入力するとidが1~始まりますが、 これを1000~開始する方法が分かりません、ご教授お願いします。 CREATE TABLE addressbook ( id smallint(4) UNSIGNED NOT NULL auto_increment, name1 varchar(20) default NULL, birthday date default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=sjis;

    • ベストアンサー
    • MySQL
  • トランザクションとlast_insert_id

    トランザクション中にinsertする予定のテーブル(未コミット)のauto_increment値を取得することはできるのでしょうか。 以下のような処理を期待しているのですが、hoge1テーブルのauto_increment値が取得できずに困っております。last_insert_id に関わらず、hoge1テーブルのauto_increment値が取得できる方法があれば教えてください。 (1) トランザクション開始 (2) $sql=" INSERT INTO hoge1(name) value('あああ'); "; (3) ( ロールバック ) (4) $key=mysql_insert_id(); (5) $sql2=" INSERT INTO hoge2(hoge1_primary,age) value($key,'20歳'); "; (6) ( ロールバック ) (7) コミット (8) トランザクション終了 よろしくお願いします。 環境: php5,mysql5 (InnoDB)

    • ベストアンサー
    • MySQL
  • FOREIGN KEYの追加について。

    FOREIGN KEYの追加について。 MySQL5.1.37 CREATE TABLE `goods` ( `id` int NOT NULL AUTO_INCREMENT, `num` int NOT NULL DEFAULT '1', PRIMARY KEY (`id`), index (`num`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `sales` ( `id` int NOT NULL AUTO_INCREMENT, `num` int NOT NULL DEFAULT '1', PRIMARY KEY (`id`), index (`num`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 上記のようなテーブルを作り、salesテーブルにCSVファイルからデータをインポートしたのち、FOREIGN KEYを子テーブルに追加したいのですが、下記のようなエラーになります。 ALTER TABLE `sales` ADD FOREIGN KEY ( `num` ) REFERENCES `test`.`goods` ( `num` ) ON UPDATE CASCADE ; MySQLのメッセージ: ドキュメント #1452 - Cannot add or update a child row: a foreign key constraint fails (`test`.`#sql-561_cf`, CONSTRAINT `#sql-561_cf_ibfk_1` FOREIGN KEY (`num`) REFERENCES `goods` (`num`) ON UPDATE CASCADE) データをインポートしたのちにFOREIGN KEYを追加するにはどのようにしたらいいのでしょうか?

  • この場合のSQL構文を教えてください(MYSQL5.0)

    お世話になります。下記の場合どうしたらできるかどうか教えてください。 ・商品リストテーブル  商品ID(int primary key auto_increment )  商品名(char) ・受注リストテーブル  受注ID(int primary key auto_increment )  商品ID(int)  注文者(char) 上記のように二つのテーブルに分かれています。 (1)新商品の注文が入ると、商品リストテーブルにレコードがINSERTされ 受注リストにも同時にINSERTされるとします。 (2)すでに商品リストテーブルに登録済みの商品名の場合は受注リストテーブルのみINSERTされます。 この場合、商品リストの商品IDは自動インクリメントされるので問題ないですが、受注リストの商品IDはインクリメントされません。 商品リストに新レコードができると、このリストの商品IDは新しい番号がふられますが、この新しくできた番号を受注リストの商品IDに同時にいれたいのです。 ○方法として 二つのテーブルをJOINしてレコードをINSERTできるのならしたいのですが、どうゆうSQL文を書けばいいのかわかりません。 またその方法以外にとりあえず商品リストテーブルにだけINSERTしてそのタイミングで受注リストテーブルにトリガでINSERTとかする方法もありなんでしょうか? できればJOINした方にINSERTする方法でやりたいのですが、無理なら後者のほうでもいいんですが・・・。 SQL文わかる方どうかよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • ODBC経由でMySQL5.0に auto_increment属性などを付加したテーブルを作成したい

    ODBC経由でMySQL5.0に auto_increment属性など付加した以下のテーブルを作成したいのですがODBCのSQL文はどう書けばよいのでしょうか? DROP TABLE IF EXISTS test; CREATE TABLE IF NOT EXISTS test ( a1 int(11) NOT NULL auto_increment, b1 enum('public','group','private') NOT NULL default 'public', c1 date NOT NULL default '0000-00-00', d1 mediumtext NOT NULL, PRIMARY KEY (`a1`) ) TYPE=MyISAM AUTO_INCREMENT=1 ; よろしくお願いします。

  • 外部キーを持つテーブルを作成しようとするとエラーがでます

    XAMPPバージョン1.5.4 MySQLバージョン4.1.16 という環境で、my.cnfでInnoDBを使えるように設定しています。 そして CREATE TABLE admin_roles (id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(12) NOT NULL) ENGINE = InnoDB; という非参照列idを持つadmin_rolesテーブルを作り(成功し)、さらに role_idを外部キーとしてadmin_user_roleテーブルを作成しようとすると、 Error Number: 1005 Can't create table '.\test\admin_user_role.frm' (errno: 150) CREATE TABLE admin_user_role (userid VARCHAR(12) NOT NULL, role_id BIGINT DEFAULT 0, FOREIGN KEY (role_id) REFERENCES admin_roles(id) ON DELETE CASCADE) ENGINE = InnoDB; というエラーが出てしまいます・・・ admin_user_roleの記述のどこが間違っているのでしょうか?

    • ベストアンサー
    • MySQL
  • 親子関係があるテーブル内での検索

    親のidを保持するテーブルです。 CREATE TABLE `tbl` ( `id` int PRIMARY KEY, `parent_id` int, FOREIGN KEY(`parent_id`) REFERENCES `tbl`(`id`) ) ENGINE=InnoDB; このテーブルで「parent_idがNULLで、かつ、子を持たない(親というか子でもないというか)行」 を検索したいのですが、どのようなSQLを記述すれば良いのでしょうか?

    • ベストアンサー
    • MySQL
  • AUTO_INCREMENTのあるテーブルにinsertできません(長文)

    mysql5.0.27(RedhatLinux 9)です。 属性のひとつがAUTO_INCREMENTになっているテーブルhogeに、データをinsertしたいのですが、「コラムの数が合致しない」というエラーで、insertできません。 Webをいろいろ漁って、AUTO_INCREMENTの属性は明示的に指定しないようだと理解しました。冗長で申し訳ないのですが、エラーが出た状態のものを、そのまま掲載させていただきます(テーブル名や属性名のみ変更しました)。 状態をまとめると、以下のようになります。 ・下記のテーブル定義で、テーブルは普通にcreateできた。 ・descで確認しても、ちゃんとテーブルはできているよう。 ・下記のinsert文で、その下のエラーメッセージが出て、データを登録できない。 ・どうみても、コラム数は合っている(と思う)。 ・下記のテーブル定義の属性数を適当に減らす(id, item1, item4, item6くらいにする)と、エラーが出ずデータがちゃんとinsertできる。 私はなにか、とんてもない勘違いをしているのでしょうか?かなりの時間試行錯誤しているのですが、一向にわかりません。。。 ===== テーブル定義 ===== CREATE TABLE hoge ( id MEDIUMINT UNSIGNED AUTO_INCREMENT NOT NULL, item1 VARCHAR (64) NOT NULL, item2 VARCHAR (64) NOT NULL, item3 VARCHAR (32) NOT NULL, item4 VARCHAR (64), item5 VARCHAR (64), item6 VARCHAR (16) NOT NULL, CONSTRAINT PK_HOGE PRIMARY KEY (id) ) type=innodb; CREATE INDEX IDX_HOGE_1 ON hoge(item1); CREATE INDEX IDX_HOGE_2 ON hoge(item2); CREATE INDEX IDX_HOGE_3 ON hoge(item3); CREATE INDEX IDX_HOGE_4 ON hoge(item4); CREATE INDEX IDX_HOGE_5 ON hoge(item6); ===== descの出力 ===== +---------------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------------+-----------------------+------+-----+---------+----------------+ | id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment | | item1 | varchar(64) | NO | MUL | | | | item2 | varchar(64) | NO | MUL | | | | item3 | varchar(32) | NO | MUL | | | | item4 | varchar(64) | YES | MUL | NULL | | | item5 | varchar(64) | YES | | NULL | | | item6 | varchar(16) | NO | MUL | | | +---------------------+-----------------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec) ===== insert文 ===== insert into hoge (item1, item2, item3, item4, item5, item6) values ( 'data1','data2', 'data3', 'data4', 'data5', 'data6'); ===== エラーメッセージ ===== ERROR 1136 (21S01) at line 1: Column count doesn't match value count at row 1 長文大変申し訳ありません。よろしくお願いします。

  • ユーザ情報を格納するテーブルについて

    MySQLバージョン4.1.16を使用しています。 基本となるユーザ情報を格納するテーブルで、 自動インクリメントされるidというカラムを使用する場合と、 使用しない場合とでは、どちらが良いというのはあるのでしょうか? みなさんはどちらの形で利用しているのでしょうか? [userinfoテーブル] id使用 id UNSIGNED AUTO_INCREMENT PRIMARY KEY user_id VARCHAR(12) UNIQUE password TINYTEXT [userinfoテーブル] id使用しない user_id VARCHAR(12) PRIMARY KEY password TINYTEXT

    • ベストアンサー
    • MySQL