sql >> データベース >  >> RDS >> PostgreSQL

競合を追加したにもかかわらず、postgresのシリアルが増加しています何もしません

    これが奇妙に感じる理由は、挿入操作の一部としてカウンターの増分を考えているためです。したがって、「何もしない」は「何も増分しない」ことを意味するはずです。あなたはこれを描いています:

    1. 制約に対して挿入する値を確認します
    2. 重複が検出された場合は中止します
    3. 増分シーケンス
    4. データを挿入

    ただし、実際には、増分は挿入が試行される前に発生する必要があります。 。 SERIAL Postgresの列はDEFAULTとして実装されています nextval()を実行します バインドされたSEQUENCEで関数 。 DBMSがデータに対して何かを実行する前に、列の完全なセットが必要であるため、操作の順序は次のようになります。

    1. シーケンスのインクリメントなど、デフォルト値を解決します
    2. 制約に対して挿入する値を確認します
    3. 重複が検出された場合は中止します
    4. データを挿入

    これは、重複するキーが自動インクリメントフィールド自体にある場合に直感的に確認できます。

    CREATE TABLE foo ( id SERIAL NOT NULL PRIMARY KEY, bar text );
    -- Insert row 1
    INSERT INTO foo ( bar ) VALUES ( 'test' );
    -- Reset the sequence
    SELECT setval(pg_get_serial_sequence('foo', 'id'), 0, true);
    -- Attempt to insert row 1 again
    INSERT INTO foo ( bar ) VALUES ( 'test 2' )
         ON CONFLICT (id) DO NOTHING;
    

    明らかに、これはシーケンスをインクリメントせずに競合があるかどうかを知ることができないため、「何もしない」はに来る必要があります その増分。



    1. Oracle sqlチュートリアル:基本的なSQLステートメント

    2. SQLPlusまたはPL/SQLでメニューを作成する方法

    3. 5データベース監視を改善するためのSQL構文とクエリの原則

    4. SQLite onUpgrade()のフラストレーション