ID重複例(雇用調整助成金の記事を見て)


はじめに

雇用調整助成金オンライン申請に関する記事を見て、
じゃあ どんなときにIDが重複するのかを、私の経験を元にまとめました。

最大値+1

[果物マスタ]

ID 果物
1 りんご
2 みかん
3 いちご
: :
4 バナナ ( ← 同時に登録 )
4 ぶどう ( ← 同時に登録 )

この場合、最大値3+1、すなわち「4」が次のIDです。

しかし複数のプロセスが「同時」に最大値を取得すると、
両プロセスともに「4」という重複IDが割り振られてしまいます。
(一方が4、他方が5とはならない。)

コーディングにもよりますが、重複IDだけ割り振られて、
ぶどうの insert エラーをシステムが適切に処理しなかった場合、
ぶどうを登録したユーザに対して
「4:バナナ が正常に登録されました」
と、身に覚えのないメッセージが表示されるでしょう。

※「最大値+1」が悪いわけではなくて、
設計やコーディングが甘いことが問題です。

ランダム値

[果物マスタ]

ID 果物
13245 りんご
97860 みかん
82073 いちご
: :
56718 バナナ ( ← ランダム値が重複 )
56718 ぶどう ( ← ランダム値が重複 )

random_int() などで得られるランダム値をIDにする設計も、
たまに見かけます。これも重複IDが発生し得ます。

マスタを同時刻に登録しようとして、偶然、同じランダム値が
生成される可能性は、ゼロではありません。

IDの頭に「年月日時分秒」を付けても同じです。
同時刻に同じランダム値が生成されれば、意味がありません。

ID使いまわし + 未削除データ

前述の「最大値+1」の場合ですが、
「4:バナナ」を削除したら、次回 登録時、
再度「4」が割り振られてしまいます。

[果物マスタ(親)]

ID 果物
1 りんご
2 みかん
3 いちご
4 ぶどう ( ←「4:バナナ」を削除後 登録 )

[生産地マスタ(子)]

ID 果物
1 青森
2 和歌山
3 栃木
4 フィリピン ( ← 未削除データのため「山梨」を登録できない!)

このとき共通IDの別テーブルに、
例えば果物マスタの子テーブル「生産地マスタ」に、
バナナの生産地「4:フィリピン」が うっかり消されずに残っていたら、
ぶどうの生産地が登録できないかもしれません。

まとめ?

主キー、排他制御、トランザクション、AUTO_INCREMENT、シーケンス等を
システムに合わせて設計して、重複しないID生成を心がけましょう。