2016-08-17 4 views
0

私は質問があります。それはおそらく理論的なことです。私は、テーブルのフィールドidをインクリメントすることで、どのように値を壊すかを理解できません。私は1つのデータベースサーバーと5つのクライアントを持っています。彼らは数時間のうちに同時にこのテーブルにデータを書き込みます。データには何千ものエントリが含まれます。Postgresのシーケンスを壊すには?

だから時にはシーケンスが壊れることがあります。私はそれが現在の値を持っていることを意味し、その最大値はidフィールドであり、その結果、INSERTの後にエラーが発生し、これは既存のidの値に関連しています。

E.g。場合によっては、テーブルにidのエントリがあり、現在の値がsequenceであり、新しいエントリのフィールドにはidの値が返されます。そして、この現在の値は、既存のエントリの等しいidになります。

これはクライアント側で修正されています。クエリによってエラーを処理します。

SELECT setval('table_id_seq', COALESCE((SELECT MAX(id)+1 FROM table), 1), false); 

しかし、このエラーの原因を防ぐ方法を知りたいのですが。

私はLinuxコンテナ(Docker)の中で起動したpostgresql 9.5を持っています。

+2

これはエラーではありません。シリアル/シーケンスはギャップフリーであることは保証されません。ただ彼らはギャップがないと仮定しないでください。 – wildplasser

+0

私はこれを理解しています。しかし時にはシーケンスの現在の値は最大のidより小さくなることがあります。 – ANtlord

+0

シーケンス(またはアプリケーション・プログラム)がシーケンスまたはターゲット列に割り当てられない場合、これは起こりません。 (もちろんラップアラウンドまで) – wildplasser

答えて

0

シーケンスのようなサウンドが明示的に設定されています。 setvalは、シーケンスを現在の最大IDより小さい値に設定した場合にこれを行うことができます。デフォルト値と既存の値が衝突すると、エラーが発生します。

さらに大きな値を持つIDを明示的に追加することができます。この場合、順序は列に値が指定されていない場合にのみ評価され、後で終了します。

このような場合は、絶対にINSERTを明示的なIDにしないでください。決してsetvalを絶対に呼び出さないでください。それでエラーは決して起こらないはずです(あなたはIDの隙間を得ることができますが、紛争のエラーは発生しません)。

+0

私は明らかに私の問題を説明しているようです。私の悪い。私は明確にしようとする。 私はそれを検出したときに 'setval'を追加しました。時々シーケンスが壊れることがあります。例えば。私はこの問題を見つけました。この後、 'setval'を追加しました。クエリがエラー終了したときにのみ動作します。 また、私はIDを明示的に指す場所がありません。 – ANtlord

+0

明示的なIDを挿入していないことを確認してください。私が何度も見たことの1つは、ID付きのテーブルを持って来るが後にシーケンスをセットすることができないCOPYコマンドです。これは、ユーザーが独自の論理バックアップソリューションを使用する場合に特に一般的です。 –

+0

私は明白なidsやsetvalがなくても、シーケンスが背後に来るのを決して見たことがありません。 –

関連する問題