理解しておくべき重要なことは、SQLテーブルには順序がないということです。 。 SELECT
を実行したときに表示される行の順序 ORDER BY
なし データベースが他の順序よりもその順序でそれらを取得する方が速いため、同じままであるだけです。 PostgreSQLは、テーブルに対してシーケンシャルスキャンを実行した場合にのみ、この順序で行を返します。クエリにインデックスを使用できる場合は、通常、他の順序で行を取得します。
私が以前に書いたこの答えが参考になるかもしれません。
PostgreSQLでは、UPDATE
sを行に移動すると、それらをテーブル内の別の場所に移動して、返される順序を変更できます。したがって、バックグラウンドの自動バキュームプロセスや、VACUUM
などの他のさまざまな操作も可能です。 およびCLUSTER
。
したがって、絶対にしてはいけません 何でも「デフォルト」の順序に依存します。行に何らかの順序を付けたい場合は、必須 それらを並べ替えることができるキーを持っています。
キーなしでテーブルを作成し、キーが必要であることに気付いた場合は、ctid
を使用して状況から回復できる可能性があります。 システム列。 しない これは本番環境での使用に依存しています。これはシステム内部の列であり、緊急時の復旧と診断の目的でのみユーザーに表示されます。まず、ディスク上の物理的な順序が実際に必要な順序であるかどうかを確認します。
SELECT row_number() OVER () AS mytable_id, *
FROM mytable
ORDER BY ctid;
そうである場合は、ディスク上の行の順序で適用される自動インクリメントされたキーに事前設定された新しいキー列を追加できます。これを行うには2つの方法があります。最も安全なのは:
BEGIN;
LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE;
ALTER TABLE mytable RENAME TO mytable_old;
CREATE TABLE mytable (id SERIAL PRIMARY KEY, LIKE mytable_old INCLUDING ALL);
INSERT INTO mytable
SELECT row_number() OVER () AS id, *
FROM mytable_old
ORDER BY ctid;
SELECT setval('mytable_id_seq', (SELECT max(id)+1 FROM mytable));
COMMIT;
結果に満足していることを確認したら、DROP TABLE mytable_old;
。このデモを参照してください:http://sqlfiddle.com/#!12 / 2cb99 / 2
すばやく簡単ですが安全性の低い方法は、列を作成し、PostgreSQLがテーブルを最初から最後まで書き直すことに依存することです。
ALTER TABLE mytable ADD COLUMN mytable_id SERIAL PRIMARY KEY;
絶対に保証はありません 実際にはそうしますが、PostgreSQLはIDを順番に割り当てます。このSQLFiddleデモをご覧ください。
SEQUENCE
を使用する場合は注意してください (これはSERIAL
列が作成します)予期しない動作がいくつかあります。一度に複数の行を挿入する場合、行は必ずしも期待どおりの順序でIDが割り当てられるとは限らず、IDが割り当てられて挿入された順序とは異なる順序で「表示」(表示される)される場合があります。また、トランザクションがロールバックすると、生成されたIDは永久に破棄されるため、番号付けにギャップが生じます。これは、データベースを高速にしたい場合には非常に便利ですが、ギャップのない番号付けが必要な場合は理想的ではありません。それが必要な場合は、「postgresqlギャップレスシーケンス」を検索してください。