🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

3回答

621閲覧

【MySQL】idにレコードがない場合について

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

2クリップ

投稿2019/12/27 14:14

編集2019/12/27 14:18

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
MySQLでデータベースを作っています。

コード

これだけではないのですが、今回の質問に関するコードだけ抜き取りしました。

sql

1create table users ( 2 id int unsigned primary key auto_increment, 3 name varchar(20) 4);
+----+---------+ | id | name | +----+---------+ | 1 | taguchi | | 2 | fkoji | | 3 | aoki | | 4 | tanaka | | 5 | yamada | | 6 | tashiro | +----+---------+

以上の様にidが連番で自動で指定してくれる様にしました。
その際に、scoreが6.0点以上のレコードを削除しました。その際のテーブルが下記の様になりました。

+----+---------+-------+ | id | name | score | +----+---------+-------+ | 1 | taguchi | 5.8 | | 4 | tanaka | 4.2 | +----+---------+-------+

そこで、質問があります
idの2~3にレコードがないのがわかると思います。

途中のidにレコードがないのはいいのでしょうか?それともidが途中でないのは良くなく詰めて以下の様にした方が良いのでしょうか?

+----+---------+-------+ | id | name | score | +----+---------+-------+ | 1 | taguchi | 5.8 | | 2 | tanaka | 4.2 | +----+---------+-------+

説明が難しく説明不足ですがお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/12/27 22:01

回答依頼いただきましたが、既に的確な回答ついてますので、そちらで。
m.ts10806

2019/12/27 22:07

と思ったんですが、幾つかケース挙げておきます。
退会済みユーザー

退会済みユーザー

2019/12/28 08:07

ご回答ありがとうございます。 順番に確認させていただきます。
guest

回答3

0

詰めた場合の弊害で今でてなさそうなのだけ挙げておきます。

・詰めるロジックが複雑、定義が無駄

1,2,3あって2が抜ける→2以上のレコードにマイナス1をする
1,2,3あって1が抜ける→1以上のレコードにマイナス1をする
ようなロジックになりますが、レコードが多ければ多いほど、更新にそれだけ負荷がかかる。

しかも定義がauto_incrementになってますよね。
1,2,3あって3が抜ける→次が4になるのでinsertしたあとにupdateするかIDを別途取得すべくmax+1をすることになる。
auto_incrementの意味なしです。

・URLからIDを引いてアクセスする仕組みの場合、URLが変わることになる

そもそも「ID」は「Identification」の略です。
「識別」とか「同一」とかいうものですね。
日本で言えば「マイナンバー」がそれに当たります。
ですので、「別の人にその番号が付与される」なんてことはあってはいけませんよね?
マイナンバーも亡くなったとして、他の人のナンバーがずれるということはないと思います(あったとしたら全部発行しなおしです)

なので、弊害が多い云々以前に、「変わる可能性がある情報にIDと名付けるべきではない」というのが実際です。
基本的にはそれだけで一意となるべきものです(それにそもそもプライマリキーになっている情報は変更しちゃダメですよ)

投稿2019/12/27 22:49

編集2019/12/27 23:20
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/12/28 08:43

>詰めるロジックが複雑、定義が無駄 idのどこが抜けているのかを探してあげて、その度にINSERT文を実行してあげなければならないのですね・・確かにそれは高コストです。 >マイナンバーも亡くなったとして、他の人のナンバーがずれるということはないと思います(あったとしたら全部発行しなおしです) >基本的にはそれだけで一意となるべきものです なるほど。わかりやすい例でイメージかつきました. 単なるレコードにふった番号ではなく、識別するための番号だという認識をもっていればidをふりなおす必要はなかったですね。 >(それにそもそもプライマリキーになっている情報は変更しちゃダメですよ) これは、知らなかったです。PHPマニュアルのここのあたりをもう一度読み直してみます。 https://www.php.net/manual/ja/faq.databases.php
m.ts10806

2019/12/28 09:17

>idのどこが抜けているのかを探してあげて、その度にINSERT文を実行してあげなければならないのですね・・確かにそれは高コストです。 insert不要です。 delete直後にそのidより大きいidに対して-1をupdateするだけです。 update users set id = id -1 where id > {delete_id} 回答に書いてあるように「データが増えれば増えるほど更新対象が多くなって高コスト」となります。 >(それにそもそもプライマリキーになっている情報は変更しちゃダメですよ) これは、知らなかったです。PHPマニュアルのここのあたりをもう一度読み直してみます。 そこはPHPやプログラミングやシステムと言うより常識の範囲です。 「特定可能な一意の情報」はどのような事情であれ変更してはいけません(名前とかも変更のためには特別な事情や制約があります)。 ※ちなみに携帯番号は「絶対に個人とつながるわけではない」という点で「特定可能な情報」ではありません。1人複数持てるし解約したらその番号使えるようになります。 身近な例で「マイナンバー」が最も分かりやすいですね。 一応、「学校における出席番号」も一意になり得ます。 ○○学校の1年2組の15番となると1人しかいないですしね。 身近なものをデータベース化してみると面白いと思いますよ。
退会済みユーザー

退会済みユーザー

2019/12/28 12:15

>「特定可能な一意の情報」はどのような事情であれ変更してはいけません(名前とかも変更のためには特別な事情や制約があります)。 逆にころころと変えられてしまうと問題が生じてくる事は少し考えただけでも沢山でてきました。 >身近なものをデータベース化してみると面白いと思いますよ。 是非、1度この機会に行なってみたいと思います。 チャット機能は、データを挿入して表示するなどの構造(?)そのようなものも実装してみたいと思います。
m.ts10806

2019/12/28 12:20

>チャット機能は、データを挿入して表示するなどの構造(?)そのようなものも実装してみたいと思います。 あ、いえ。あくまで「身近なもの」です。 先に出した出席番号の件もそうですし、住所とかグループとかクラブ活動とか、図書の貸し出しとか、そういう本当に身近なものです。 システムって結構どこにでもあてはめられるものです。
退会済みユーザー

退会済みユーザー

2019/12/28 12:23

では、ちょうどクラスの名簿があったのでそれをもとに制作していきます。
m.ts10806

2019/12/28 12:43

うまく伝わってるといいんですが・・・ 実際に制作するというより、設計技術を磨くために役に立つという話ですね。 数学に強い大学生とかは町中に溢れている数字を見つけては足したり引いたりするのが癖になっているという話を聞いたことがあるのですが、 それと似たようなもので、日ごろから「システム構造」というのを考える癖をつけておくことで、知らず知らずのうちに設計力が身についていくもんです。 ですので、「さぁやることを決めて作るぞ」ではなく「これどういう仕組みで作れるだろう」「どうなってるんだろう」というのを常日頃から身近なものに対して考える癖をつけようという話です。
退会済みユーザー

退会済みユーザー

2019/12/28 13:16 編集

今回の質問も名簿からデータベースを制作した時、idが再代入されてはいけない事と気づくはずですよね。その様に他にもこれはどの様な仕組みになっているのだろう?など実際に考える癖をつけた方が良いという話ですよね。 理科でもあるように「この仕組みはどうなっているのだろう?」など考え、自分で積極的に実験をし自分の目で確かめる癖をつけていく習慣があると良い。という認識をしています。
m.ts10806

2019/12/28 13:10

うーん。ちょっと難しく考えすぎですね。
guest

0

yuokadaさんと同じく、idを変えるのは弊害があるので避けた方が良いと思います。
レスポンス以外の弊害を挙げると、他のテーブルとの関係が保てなくなる可能性があります。

例えば、次のようなgroupテーブルの代表者idが、userテーブルのidを参照しているとします。
+-------+------------+
| group| 代表者id |
+-------+------------+
| A | 1 |← taguchiさんがAグループの代表
| B | 2 |← fkojiさんがBグループの代表
+-------+------------+
userテーブルから id=2 の fkoji さんが削除されたのであれば、Bグループの代表者がいなくなったと解釈されるべきです。しかし、userテーブルでidを詰めてしまうと tanaka さんが id=2 になるため、Bグループの代表者が意図せず tanaka さんに変わったかのように解釈されてしまいます。

投稿2019/12/27 15:06

AkihiroIshii

総合スコア67

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/12/28 08:17

>他のテーブルとの関係が保てなくなる可能性があります。 >Bグループの代表者が意図せず tanaka さんに変わったかのように解釈されてしまいます。 なるほど。イメージのつきやすい解説ありがとうございます。 id=2に設定した代表者が、tanakaさんに変更されてしまうのですね。勉強になりました。ありがとうございます。
guest

0

ベストアンサー

結論だけ書くとその状況で全く問題ないです。
idを詰めるということはIDを使い回すということになります。

IDを使い回すためにはどこのID抜けているのか新しいレコードの追加の度に検索してからINSERT文を実行する必要があり、それは非常に高コストな作業です。

テーブルのレコードの数が1000件程度なら問題なく動作するかもしれませんが100万件程度まで膨れ上がるとそういった仕様で動かした場合にレスポンスがかなり悪くなります。

それ以外にもIDを使い回すことの弊害がいくつかありますがその辺りの回答は他の回答者さんにお任せしたいと思います。

投稿2019/12/27 14:40

yuokada

総合スコア550

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/12/28 08:14

>IDを使い回すためにはどこのID抜けているのか新しいレコードの追加の度に検索してからINSERT文を実行する必要があり、それは非常に高コストな作業です。 2がなかった場合3に-1をして・・とやっていくと高コストですよね。 問題がないという事なので安心しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問