45

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

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

それらは実稼働環境にあるため、既存のサーバーでそれらを変更することはできません。

問題は、主キーが一意の自動増分フィールドであるため、交差があることです。

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

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

ヘルプ!

4

10 に答える 10

30

この問題を解決するために、私はこの質問を調べ、@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% の確率で私の問題を解決します。

于 2015-02-24T19:26:13.623 に答える
28

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
于 2009-06-19T15:54:54.757 に答える
13

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

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

> CREATE VIEW myView AS
  SELECT name, email FROM users

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

于 2009-06-19T15:48:11.183 に答える
7

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

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]*,実際に必要なものを置き換えないように注意する必要があります。

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

于 2012-04-12T20:30:27.833 に答える
7
  1. テーブルのクローンを作成
  2. クローンテーブルに列をドロップします
  3. 構造なしでクローンテーブルをダンプします(ただし、完全な挿入を取得するには -c オプションを使用します)
  4. 必要な場所にインポート
于 2011-11-21T16:54:10.113 に答える
4
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をクリアします。テストされていませんが、かなり自信があります。

于 2009-06-19T16:03:52.400 に答える
2

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

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

于 2010-01-22T12:42:12.170 に答える
0

jimyiは正しい方向に進んでいました。

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

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

($ xは元のデータベースを一意に識別する1桁の数字です)ソースデータベースにビューを作成するか(これは不可能かもしれません)、Autocracyで説明されているような抽出ルーチンを使用するか、データをステージングテーブルにロードします。テストボックス。

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

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

C。

于 2010-01-22T13:15:48.357 に答える
0

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

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

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

于 2012-06-08T07:05:34.893 に答える