このselect max(id) + 1
アプローチでは、同時に挿入する 2 つのセッションがテーブルから同じ現在の最大 ID を参照し、両方が同じ新しい ID 値を挿入します。これを安全に使用する唯一の方法は、トランザクションを開始する前にテーブルをロックすることです。これは面倒であり、トランザクションをシリアル化します。(Stijn が指摘しているように、最上位のレコードが削除された場合、値を再利用できます)。基本的に、このアプローチは使用しないでください。(やむを得ない理由がある場合が非常にまれにあるかもしれませんが、実際に見たことがあるかどうかはわかりません)。
シーケンスは、2 つのセッションが異なる値を取得することを保証し、シリアル化は必要ありません。パフォーマンスが向上し、安全性が向上し、コーディングが容易になり、保守が容易になります。
シーケンスを使用して重複エラーが発生する唯一の方法は、シーケンス値を超える ID を持つレコードがテーブルに既に存在する場合、またはシーケンスを使用せずに何かがまだレコードを挿入している場合です。したがって、たとえば 1 から 10 までの ID が手動で入力された既存のテーブルがあり、デフォルトの start-with 値 1 でシーケンスを作成した場合、シーケンスを使用した最初の挿入では ID 1 を挿入しようとしますが、これは既に存在します。 . これを 10 回試行すると、シーケンスは 11 回になり、これでうまくいきます。次に max-ID アプローチを使用して 12 を使用する次の挿入を行った場合、シーケンスはまだ 11 のままであり、次に を呼び出したときにも 12 になりますnextval
。
シーケンスとテーブルは関係ありません。手動で生成された ID 値がテーブルに挿入された場合、シーケンスは自動的に更新されないため、2 つのアプローチが混在することはありません。(とりわけ、ドキュメントに記載されているように、同じシーケンスを使用して複数のテーブルの ID を生成できます)。
手動アプローチからシーケンス アプローチに変更する場合は、テーブル内の既存のすべての ID よりも大きい start-with 値でシーケンスが作成されていること、および挿入を行うすべての操作でシーケンスが使用されていることを確認する必要があります。将来的にのみ。