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

4,000万レコードのテーブルに複数列の主キーを追加する

    シリアル列を使用する

    あなたの計画は、4000万(!)行の不必要に巨大なインデックスを追加することです。そして、あなたはそれがユニークになるかどうかさえ確信していません。私はその行動経路に反対することを強くお勧めします。 シリアル 代わりに列を作成してください:

    ALTER TABLE tbl ADD COLUMN tbl_id serial PRIMARY KEY;
    

    それはあなたがする必要があるすべてです。残りは自動的に行われます。マニュアルまたはこれらの密接に関連する回答の詳細:
    C++でPostgreSQLの主キーの自動インクリメントがクラッシュする
    SQL関数の自動インクリメント

    シリアルの追加 カラムは1回限りの操作ですが、コストがかかります。テーブル全体を書き直して、操作中の更新をブロックする必要があります。営業時間外に同時ロードせずに行うのが最適です。 ここのマニュアル を引用します :

    これによりテーブル全体が効果的に書き換えられるため、シリアルpk列を使用して新しいテーブルを作成し、古いテーブルからすべての行を挿入し、シリアルにシーケンスのデフォルト値を入力させ、古いものを削除して新しい名前を変更することもできます。これらの密接に関連する回答の詳細:
    PostgreSQL9.2でテーブルをロックせずにデータベース行を更新する
    テーブルなしで新しい列を追加ロックしますか?

    すべてのINSERTステートメントにターゲットリストがあることを確認してください。そうすれば、追加の列でそれらを混乱させることはできません。

    INSERT INTO tbl (col1, col2, ...) VALUES ...

    ない:

    INSERT INTO tbl VALUES ...

    シリアル integerで実装されています 列(4バイト)。
    主キー制約は、一意のインデックスと NOT NULLを使用して実装されます。 関連する列に対する制約。
    インデックスの内容は、テーブルのように格納されます。追加の物理ストレージは別途必要です。この関連する回答の物理ストレージの詳細:
    PostgreSQLのスペースの計算と節約

    インデックスには、2つのタイムスタンプ(2 x 8バイト)と長いファイル名が含まれます。パス(〜50バイト?)これにより、インデックスが約2.5 GB大きくなり(40M x 60 ..何かバイト)、すべての操作が遅くなります。

    重複の処理

    「重複のインポート」の処理方法は、データのインポート方法と「重複」の正確な定義方法によって異なります。

    コピーについて話している場合 ステートメントの1つの方法は、一時的なステージングテーブルを使用し、単純な SELECT DISTINCTで重複を折りたたむことです。 またはDISTINCTON 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を使用してサーバー側スクリプトを作成する必要があります。



    1. OracleODP.NETバージョンに依存しない代替

    2. plsqlでzipフォルダを作成する方法(Oracle)

    3. CentOS6にCassandrav3をインストールする方法

    4. DBのフェイルオーバーサポート