• 作成:

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を付加していたので, それに逆らって設定で消していくのも一々しんどい.