web-dev-qa-db-ja.com

主キーをダンプしないmysqldumpテーブル

MySql 4を実行している2台のサーバーにまたがる1つのテーブルがあります。これらをテスト環境用に1台のサーバーにマージする必要があります。

これらのテーブルには文字通り数百万のレコードがあり、それらが2つのサーバー上にある理由は、それらが非常に大きいためです。テーブルの変更とページングは​​、パフォーマンスに大きな影響を与えます。

これらは実稼働環境にあるため、既存のサーバーで何らかの方法で変更することは不可能です。

問題は、主キーが一意の自動インクリメントフィールドであるため、交差があることです。

私はmysqldumpコマンドを使用して特定のフィールドを無視する方法を理解しようとしましたが、--disable-keysは、キーを完全に削除するのではなく、単にテーブルを変更します。

この時点で、データベース構造を変更して、主キーのチェックサムまたはハッシュを、実際には一意である必要がある2つの一意のフィールドの組み合わせとして利用する必要があるように見えます...私は本当にしたくありませんこれを行う。

助けて!

40
Zee Spencer

auto_incrementカラムの値が気にならない場合は、最初のファイルをロードし、テーブルの名前を変更してから、テーブルを再作成して2番目のファイルをロードします。最後に、使用

INSERT newly_created_table_name (all, columns, except, the, auto_increment, column)
       SELECT all, columns, except, the, auto_increment, column
         FROM renamed_table_name
26
longneck

この問題を解決するために、私はこの質問を調べ、@ pumpkintheheadの答えを見つけ、mysqlが代わりにデフォルトのauto_increment値を使用するように、各行の主キーをNULLで見つけて置き換えるだけでよいことに気付きました。

(your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql

元の出力:

INSERT INTO `core_config_data` VALUES
    (2735,'default',0,'productupdates/configuration/sender_email_identity','general'),
    (2736,'default',0,'productupdates/configuration/unsubscribe','1'),

変換された出力:

INSERT INTO `core_config_data` VALUES
    (NULL,'default',0,'productupdates/configuration/sender_email_identity','general'),
    (NULL,'default',0,'productupdates/configuration/unsubscribe','1'),

注:これはまだハックです。たとえば、自動インクリメント列が最初の列ではない場合は失敗しますが、問題は99%解決されます。

22
Eric Seastrand

主キー列のないテーブルのビューを作成し、そのビューでmysqldumpを実行できます。

したがって、テーブル「users」に次の列がある場合:id、name、email

> CREATE VIEW myView AS
  SELECT name, email FROM users

編集:ああ、なるほど。他に方法があるかどうかはわかりません。

12
jimyi
  1. テーブルのクローンを作成
  2. クローンテーブルの列を削除します
  3. 構造なしでクローンテーブルをダンプします(ただし、完全な挿入を取得するには-cオプションを使用)
  4. 必要な場所にインポート
6
Fedir RYKHTIK

これは完全な痛みです。私は次のようなものを実行することでこの問題を回避します

sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql 

ダンプで主キーを削除してから、

sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql

主キーを除くすべての列。もちろん、あなたは([0-9]*,は、実際に必要なものを置き換えません。

それが誰かを助けることを願っています。

6
pumpkinthehead
SELECT null as fake_pk, `col_2`, `col_3`, `col_4` INTO OUTFILE 'your_file'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM your_table;

LOAD DATA INFILE 'your_file' INTO TABLE your_table
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';

追加の空想のために、挿入が発生する前にリーチ行の新しい主キーを設定する受信テーブルに挿入前トリガーを設定できます。これにより、通常のダンプを使用し、依然としてpkをクリアします。テストされていませんが、かなり自信があります。

4
Jeff Ferland

ダミーの一時主キーを使用します。

通常はmysqldumpを使用してください--opts -c。たとえば、主キーは「id」です。出力ファイルを編集し、「dummy_id」という行をテーブルの構造に「id」と同じタイプで追加します(もちろん、主キーではありません)。次に、INSERTステートメントを変更し、「id」を「dummy_id」に置き換えます。インポートしたら、列「dummy_id」をドロップします。

2
LinuxMatt

jimyiは正しい軌道に乗っていました。

これが、自動インクリメントキーがPITAである理由の1つです。 1つの解決策は、データを削除せずに追加することです。

CREATE VIEW myView AS
SELECT id*10+$x, name, email FROM users

($ xは元のデータベースを一意に識別する1桁の数字)ソースデータベースにビューを作成する(ヒントできない場合があります)か、オートクラシーで説明されているような抽出ルーチンを使用するか、データをステージングテーブルにロードしますテストボックス。

または、テストシステムでテーブルを作成しないでください。代わりに、srcデータ用の個別のテーブルに配置して、両方からフェッチするビューを作成します。

CREATE VIEW users AS
(SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b)

C.

0
symcbean

一時テーブルのルートが好きです。

create temporary table my_table_copy
select * from my_table;

alter table my_table_copy drop id;

// Use your favorite dumping method for the temporary table

他のものと同様に、これは万能のソリューションではありません(特にOPの数百万行)、10 ^ 6行でも実行には数秒かかりますが機能します。

0
Aidan Miles

私が使用してきた解決策は、エクスポートするデータの通常のSQLエクスポートを実行してから、RegEx検索置換エディターを使用して、挿入ステートメントから主キーを削除することです。個人的にはSublime Textを使っていますが、TextMateやNotepad ++などでも同じことができると思います。

次に、HeidiSQLのクエリウィンドウまたはPHPMyAdminにクエリをコピーして貼り付けることで、データを挿入するデータベースのクエリを実行します。 [〜#〜] lot [〜#〜]のデータがある場合、挿入クエリをSQLファイルに保存し、代わりにファイルインポートを使用します。大量のテキストをコピーして貼り付けると、Chromeがフリーズすることがよくあります。

これは大変な作業のように聞こえるかもしれませんが、エクスポートとインポートの間に数分以上使用することはめったにありません。おそらく、私が受け入れたソリューションで使用するよりもはるかに少ないでしょう。私はこの解決方法を数十万行で問題なく使用しましたが、数百万に達すると問題が発生すると思います。

0
Hubro