質問編集履歴
1
一部情報追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,23 +1,28 @@
|
|
1
1
|
現在MySQL 5.5.45、InnoDBで使っています。
|
2
|
-
|
3
2
|
様々な場面で、AUTO_INCREMENTを設定した主キーの値が意図したとおりの動作にならずに困ることがあります。
|
4
3
|
|
5
4
|
特に多いのが、
|
6
5
|
- INSERT...ON DUPLICATE KEY UPDATE
|
7
6
|
- INSERT IGNORE
|
7
|
+
- REPLACE
|
8
8
|
|
9
9
|
などを使った場合のインクリメントの仕方。
|
10
10
|
|
11
11
|
「SELECTしてその値が無かったらINSERT」は多くの人が望んでいる、「よくある動作」かと思われます。
|
12
12
|
一般的な人間の思考でいくと綺麗な連番になっていてほしいものですが、実際は値が飛び飛びになっていたりすることが多いですよね。
|
13
13
|
|
14
|
+
REPLACEなどは挙動をよく理解しておかないと致命的なことになりかねません。特にオートインクリメントしたidをサロゲートキーとして使っている場合は。「マニュアル読め」と言われればそれまでですが、一般的な人間の感覚からはだいぶズレた「MySQL(DB全般?)特有の動作」と言っていいのではないでしょうか。
|
15
|
+
|
16
|
+
---
|
17
|
+
|
14
18
|
参考:[【MySQL】AUTO_INCREMENTの値が増える、飛ぶ、欠番が発生する at softelメモ](https://www.softel.co.jp/blogs/tech/archives/2651)
|
15
19
|
|
16
|
-
|
17
20
|
参考:[insert duplicate インクリメント - Google 検索](https://www.google.co.jp/search?q=insert+duplicate&rlz=1C1TWJA_jaJP505JP506&oq=insert+dup&aqs=chrome.4.69i57j69i65l3j0l2.5541j0j7&sourceid=chrome&ie=UTF-8#q=insert+duplicate+%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88)
|
18
21
|
|
22
|
+
参考:[サロゲートキー](https://www.google.co.jp/search?q=%E3%82%B5%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%88%E3%82%AD%E3%83%BC&rlz=1C1TWJA_jaJP505JP506&oq=%E3%82%B5%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%88%E3%82%AD%E3%83%BC&aqs=chrome..69i57j0l5.151j0j4&sourceid=chrome&ie=UTF-8) - Google 検索
|
19
23
|
|
20
24
|
|
25
|
+
---
|
21
26
|
たとえば
|
22
27
|
id AUTO_INCREMENT 主キー
|
23
28
|
name unique
|
@@ -26,13 +31,15 @@
|
|
26
31
|
INSERT IGNORE INTO `member` (`name`) VALUES(:name);
|
27
32
|
```
|
28
33
|
を投げると、id値は「1,2,4」となります。
|
29
|
-
|
30
34
|
実用上はそれでも問題ないのかもしれませんが、人間の心情的にはidを連続した値にしてほしいところです。
|
31
35
|
|
32
36
|
こういうとき、地道にSELECTして値の存在を確認してからINSERT・・・などと回りくどいことをせずに一発でスマートに(連番で)解決する方法は存在するのでしょうか?
|
33
37
|
それともデータベースとはそういうものなのだ、と諦めるしかないのでしょうか?
|
34
38
|
|
35
39
|
|
40
|
+
---
|
41
|
+
|
42
|
+
|
36
43
|
参考:[kamipo TRADITIONALでは防げないINSERT IGNOREという名の化け物 | おそらくはそれさえも平凡な日々](http://www.songmu.jp/riji/entry/2015-07-20-insert-ignore.html)
|
37
44
|
|
38
45
|
参考:[songmuさんのツイート: "我々は何故2015年にもなってSELECTして無かったらINSERTする場合のベストパターンを確立できていないのか。"](https://twitter.com/songmu/status/621672337784451073?ref_src=twsrc%5Etfw)
|