PostgreSQLアンチパターン 自動採番される疑似キーを手動で入力する
SQL全般の話ではなくPostgreSQLの話です.
- IDリクワイアド
- Pseudokey Neat-Freak(疑似キー潔癖症)
に関連するアンチパターン.
運用の問題なのでアンチパターンではないかもしれません.
問題
id bigint not null default nextval('foo_id_seq'::regclass)
のような自動採番される人工キーに対して,
自動採番のシステムを通さないで,
id
手動で指定してinsert
で入力してしまうと,
次のinsert
時にIDがユニーク制約違反になってエラーになります.
もちろんRDBMSにもよるのでしょう. 今回発生したのはPostgreSQL上での話です.
PostgreSQLでINSERT時に自動採番の主キーが重複してエラーが出る場合の対処法 -- ぺけみさお
PostgreSQLは自動採番する時に自動採番用インデックスデータをインクリメントしてその値を使うので,
自動採番システムを通さないでid
を入力してしまうと次回の入力時にinsert
がエラーになってしまうんですね.
そしてシステムは止まり, 決済は中途半端な状態で発行されてしまい, ユーザからの信頼は消失します.
insert
したのは私ではありませんが,
任せたのは私ですし,
ユーザにとっては関係ないと思うので,
非公式で何もわからないと思いますがわかる人向けに謝っておきます.
ごめんなさい.
これは他の人がやらないための業界向けの技術記事であり,
謝罪記事ではありませんが,
重ねて謝っておきます.
解決策
自動採番キーを手動で入力しない
このことがわかっていれば問題はない.
SQLコンソールで人がinsertしない
まともな解決策.
しかしそもそも人がinsertしなければいけない状況が発生してしまっていたからこの問題が発生したので, それは解決策になっていない.
人類を滅ぼすという近似解もあります.
疑似キーにUUIDを使う
自動採番にインクリメント数値を使っているから手動で入力されてしまう.
初めからUUIDを使っていれば手動で入力されることはない.
万一uuidgen
を使うほど半端にリテラシーが高い人が居てもUUIDなら後から入力されても衝突しないので無問題.
疑似キーを持たない
疑似キーを自動で付加するような軟弱なフレームワークを使わないという硬派な選択.
何気ないリソースのURLをどうやって決めるんですか, 無理では…?
ただ,
URLを提供しないようなリソースには一々id
をつける必要はないかもしれません.
既存のSQLアンチパターンであるIDリクワイアドにあるように, 一々idを付加するのは再考する必要があるでしょう.
しかし今回はマッパーが自動的にid
を付加していたので,
それに逆らって設定で消していくのも一々しんどい.