MySql 4を実行している2台のサーバーにまたがる1つのテーブルがあります。これらをテスト環境用に1台のサーバーにマージする必要があります。
これらのテーブルには文字通り数百万のレコードがあり、それらが2つのサーバー上にある理由は、それらが非常に大きいためです。テーブルの変更とページングは、パフォーマンスに大きな影響を与えます。
これらは実稼働環境にあるため、既存のサーバーで何らかの方法で変更することは不可能です。
問題は、主キーが一意の自動インクリメントフィールドであるため、交差があることです。
私はmysqldumpコマンドを使用して特定のフィールドを無視する方法を理解しようとしましたが、--disable-keysは、キーを完全に削除するのではなく、単にテーブルを変更します。
この時点で、データベース構造を変更して、主キーのチェックサムまたはハッシュを、実際には一意である必要がある2つの一意のフィールドの組み合わせとして利用する必要があるように見えます...私は本当にしたくありませんこれを行う。
助けて!
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
この問題を解決するために、私はこの質問を調べ、@ 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%解決されます。
主キー列のないテーブルのビューを作成し、そのビューでmysqldumpを実行できます。
したがって、テーブル「users」に次の列がある場合:id、name、email
> CREATE VIEW myView AS
SELECT name, email FROM users
編集:ああ、なるほど。他に方法があるかどうかはわかりません。
これは完全な痛みです。私は次のようなものを実行することでこの問題を回避します
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]*,
は、実際に必要なものを置き換えません。
それが誰かを助けることを願っています。
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をクリアします。テストされていませんが、かなり自信があります。
ダミーの一時主キーを使用します。
通常はmysqldump
を使用してください--opts -c
。たとえば、主キーは「id」です。出力ファイルを編集し、「dummy_id」という行をテーブルの構造に「id」と同じタイプで追加します(もちろん、主キーではありません)。次に、INSERT
ステートメントを変更し、「id」を「dummy_id」に置き換えます。インポートしたら、列「dummy_id」をドロップします。
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.
一時テーブルのルートが好きです。
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行でも実行には数秒かかりますが機能します。
私が使用してきた解決策は、エクスポートするデータの通常のSQLエクスポートを実行してから、RegEx検索置換エディターを使用して、挿入ステートメントから主キーを削除することです。個人的にはSublime Textを使っていますが、TextMateやNotepad ++などでも同じことができると思います。
次に、HeidiSQLのクエリウィンドウまたはPHPMyAdminにクエリをコピーして貼り付けることで、データを挿入するデータベースのクエリを実行します。 [〜#〜] lot [〜#〜]のデータがある場合、挿入クエリをSQLファイルに保存し、代わりにファイルインポートを使用します。大量のテキストをコピーして貼り付けると、Chromeがフリーズすることがよくあります。
これは大変な作業のように聞こえるかもしれませんが、エクスポートとインポートの間に数分以上使用することはめったにありません。おそらく、私が受け入れたソリューションで使用するよりもはるかに少ないでしょう。私はこの解決方法を数十万行で問題なく使用しましたが、数百万に達すると問題が発生すると思います。