シリアル列を使用する
あなたの計画は、4,000 万 (!) 行の不必要に巨大なインデックスを追加することです。そして、あなたはそれがユニークになるかどうかさえ確信が持てません. 私はその行動経路に反対することを強くお勧めします。serial
代わりに列を追加して、それで完了です。
ALTER TABLE tbl ADD COLUMN tbl_id serial PRIMARY KEY;
それはあなたがする必要があるすべてです。残りは自動的に行われます。マニュアルまたはこれらの密接に関連する回答の詳細:
PostgreSQL primary key auto increment crashes in C++
Auto increment SQL function
serial
列の追加は 1 回限りの操作ですが、費用がかかります。テーブル全体を書き換える必要があり、操作中は更新がブロックされます。営業時間外に同時負荷なしで実行するのが最善です。ここでマニュアルを引用します:
null 以外の既定値を持つ列を追加するか、既存の列の型を変更すると、テーブル全体とインデックスを書き換える必要があります。[...] 大きなテーブルでは、テーブルやインデックスの再構築にかなりの時間がかかる場合があります。一時的に 2 倍のディスク容量が必要になります。
これによりテーブル全体が効果的に書き換えられるため、シリアル pk 列を含む新しいテーブルを作成し、古いテーブルからすべての行を挿入して、シリアルにそのシーケンスのデフォルト値を入力させ、古いテーブルを削除して新しいテーブルの名前を変更することもできます。これらの密接に関連する回答の詳細:
Updating database rows without locked the table in PostgreSQL 9.2
Add new column without table lock?
すべての INSERT ステートメントにターゲット リストがあることを確認してから、追加の列でそれらを混乱させることはできません。
INSERT INTO tbl (col1, col2, ...) VALUES ...
いいえ:
tbl 値に挿入 ...
Aserial
はinteger
列 (4 バイト) で実装されます。
主キー制約は、一意のインデックスとNOT NULL
関連する列の制約で実装されます。
インデックスの内容は、テーブルと同じように保存されます。追加の物理ストレージが別途必要です。この関連する回答の物理ストレージの詳細:
PostgreSQL でのスペースの計算と節約
インデックスには、2 つのタイムスタンプ (2 x 8 バイト) と長いファイル名が含まれます。パス(〜50バイト?)これにより、インデックスが約2.5 GB大きくなり(40M x 60 ..何かバイト)、すべての操作が遅くなります。
重複の処理
「重複のインポート」の処理方法は、データのインポート方法と「重複」の正確な定義方法によって異なります。
ステートメントについて話している場合、1 つの方法は、一時的なステージング テーブルを使用し、コマンドで単純なorCOPY
を使用して重複を折りたたむことです。SELECT DISTINCT
DISTINCT ON
INSERT
CREATE TEMP TABLE tbl_tmp AS
SELECT * FROM tbl LIMIT 0; -- copy structure without data and constraints
COPY tbl_tmp FROM '/path/to/file.csv';
INSERT INTO tbl (col1, col2, col3)
SELECT DISTINCT ON (col1, col2)
col1, col2, col3 FROM tbl_tmp;
または、既存の行との重複も禁止するには:
INSERT INTO tbl (col1, col2, col3)
SELECT i.*
FROM (
SELECT DISTINCT ON (col1, col2)
col1, col2, col3
FROM tbl_tmp
) i
LEFT JOIN tbl t USING (col1, col2)
WHERE t.col1 IS NULL;
温度。テーブルはセッションの最後に自動的に削除されます。
しかし、適切な修正は、最初に重複を生成するエラーの根本に対処することです。
元の質問
1) すべての列に 1 つの重複がある場合、pk をまったく追加できませんでした。
2) PostgreSQL データベースバージョン 8.1に 5 フィートの棒で触れるだけです。それは絶望的に古く、時代遅れで非効率的であり、もはやサポートされておらず、おそらく多くの未修正のセキュリティホールがあります. Postgres の公式バージョン管理サイト。
@Davidはすでに SQL ステートメントを提供しています。
3 & 4) 重複キー違反。PostgreSQL がエラーをスローすることは、トランザクション全体がロールバックされることも意味します。perl スクリプトでそれをキャッチしても、残りのトランザクションを通過させることはできません。たとえば、例外をキャッチできるplpgsqlを使用してサーバー側スクリプトを作成する必要があります。