これは数回尋ねられましたが、問題の解決策が見つかりません。基本的に、MySQL Workbench管理ツールの組み込みツールであるmysqldumpを使用する場合、拡張挿入を使用してデータベースをダンプすると、大量の長い行のデータが得られます。データを1つのコマンドとして挿入することにより(特にInnoDBで)挿入を高速化するため、これを行う理由を理解していますが、フォーマットにより、実際にダンプファイル内のデータを確認したり、diffツールで2つのファイルを比較したりすることは非常に困難ですバージョン管理などに保存している場合。私の場合、ダンプファイルを使用して統合テストデータベースを追跡するため、バージョン管理に保存しています。
これで、拡張挿入をオフにできることがわかったので、行ごとに1つの挿入を取得しますが、これは機能しますが、ダンプファイルを使用して復元を行うと、遅くなります。
私の中心的な問題は、ファイルをダンプするときに使用するOLDツール(MySQL管理者)で、基本的に同じことを行いますが、一括挿入を実行しながら、INSERTステートメントを1行に1つ挿入するようにフォーマットすることです。したがって、これの代わりに:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES (887,'0.0000'),191607,'1.0300');
あなたはこれを得る:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES
(887,'0.0000'),
(191607,'1.0300');
どんなオプションを試しても、このようなダンプを取得する方法はないようです。これは、両方の世界で最高です。はい、もう少しスペースが必要ですが、ファイルを読むために人間が必要な状況では、非常に便利になります。
私は何かを見逃していて、MySQLDumpでこれを行う方法がありますか、それとも私たちはすべて後退し、古い(現在廃止されている)MySQL Administratorツールのこの機能はもう利用できませんか?
デフォルトのmysqldump形式では、ダンプされた各レコードは、ダンプファイル(つまり、sqlファイル)に個別のINSERTコマンドを生成し、それぞれが独自の行になります。これはソース管理(svn、gitなど)に最適です。差分とデルタの解像度がより細かくなり、最終的にはより効率的なソース管理プロセスになります。ただし、サイズが非常に大きいテーブルの場合、これらのINSERTクエリをすべて実行すると、sqlファイルからの復元が非常に遅くなる可能性があります。
--extended-insertオプションを使用すると、ダンプされたsqlファイルの1行ですべてのレコードを1つのINSERTコマンドにラップすることにより、複数のINSERT問題が修正されます。ただし、ソース管理プロセスは非常に非効率的になります。テーブルの内容全体がsqlファイルの1行で表されます。1文字がそのテーブルのどこかで変更されると、ソース管理は行全体(つまりテーブル全体)にバージョン間のデルタとしてフラグを立てます。また、大きなテーブルの場合、これは正式なソース管理システムを使用する利点の多くを無効にします。
したがって、理想的には、データベースを効率的に復元するために、sqlファイルで、各テーブルを単一のINSERTで表すようにします。効率的なソース管理プロセスのために、sqlファイルでは、そのINSERTコマンドの各レコードを独自の行に配置する必要があります。
これに対する私の解決策は、次のバックアップスクリプトです。
#!/bin/bash
cd my_git_directory/
ARGS="--Host=myhostname --user=myusername --password=mypassword --opt --skip-dump-date"
/usr/bin/mysqldump $ARGS --database mydatabase | sed 's$VALUES ($VALUES\n($g' | sed 's$),($),\n($g' > mydatabase.sql
git fetch Origin master
git merge Origin/master
git add mydatabase.sql
git commit -m "Daily backup."
git Push Origin master
結果は、次のようなsqlファイルのINSERTコマンド形式です。
INSERT INTO `mytable` VALUES
(r1c1value, r1c2value, r1c3value),
(r2c1value, r2c2value, r2c3value),
(r3c1value, r3c2value, r3c3value);
いくつかのメモ:
次のオプションを使用してみてください。-skip-extended-insert
それは私のために働いた。
他の人がsedを使用して ")、("を置き換えると言ったように、これはデータベースのコンテンツとして表示される可能性があるため安全ではありません。ただし、これを行う方法があります。
$ mysqldump -u my_db_user -p -h 127.0.0.1 --skip-extended-insert my_database > my_database.sql
$ sed ':a;N;$!ba;s/)\;\nINSERT INTO `[A-Za-z0-9$_]*` VALUES /),\n/g' my_database.sql > my_database2.sql
「sed -i」を使用してインラインを置き換えることもできます。
このコードの動作は次のとおりです。
お役に立てれば
このような--tab
オプションを使用して、mysqldumpでCSVファイルにダンプを保存するのはどうですか?
mysqldump --tab=/path/to/serverlocaldir --single-transaction <database> table_a
これにより、2つのファイルが生成されます。
table_a.sql
テーブル作成ステートメントのみを含む;そしてtable_a.txt
はタブ区切りデータを含みます。LOAD DATA
でテーブルを復元できます:
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_a FIELDS TERMINATED BY '\t' ...
LOAD DATAは通常、INSERTステートメントを使用するよりも20倍高速です。
データを別のテーブルに復元する必要がある場合(たとえば、レビューやテストの目的で)、「ミラー」テーブルを作成できます。
CREATE TABLE table_for_test LIKE table_a;
次に、CSVを新しいテーブルにロードします。
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_for_test FIELDS TERMINATED BY '\t' ...
CSVファイルは、差分や内部を見るため、またはExcel
、Access
またはコマンドライン(diff
、comm
など...)
これは不可能だと思います。古いMySQL管理者で、dbオブジェクトをダンプするためのコードを作成しました。このコードは、mysqldumpツールとは完全に独立しており、そのため多くの追加オプション(このフォーマットや進捗フィードバックなど)を提供しました。 MySQL Workbenchでは、代わりにmysqldumpツールを使用することに決定しました。これは、いくつかの点で後退し、バージョンの問題を引き起こすことに加えて、常にサーバーを最新の状態に保つ利点があります。
簡単な答えは次のとおりです。現在、mysqldumpではフォーマットが不可能です。
このツールは、拡張挿入の処理に非常に役立つことがわかりました。 http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts.html
Mysqldump出力を解析し、各レコードの後に改行を挿入しますが、それでも高速の拡張挿入を使用します。 sedスクリプトとは異なり、文字列内で正規表現が一致した場合、間違った場所で行を壊す危険はありません。
これを試して:
mysqldump -c -t --add-drop-table=FALSE --skip-extended-insert -uroot -p<Password> databaseName tableName >c:\path\nameDumpFile.sql
このエラーが発生するまで、私はsedを使用したAce.Diのソリューションが好きでした:sed:メモリを再割り当てできませんでした
したがって、小さなPHPスクリプトを書かなければなりませんでした
mysqldump -u my_db_user -p -h 127.0.0.1 --skip-extended-insert my_database | php mysqlconcatinserts.php > db.sql
PHPスクリプトは、メモリの問題を回避するために、10.000行ごとに新しいINSERTも生成します。
mysqlconcatinserts.php:
#!/usr/bin/php
<?php
/* assuming a mysqldump using --skip-extended-insert */
$last = '';
$count = 0;
$maxinserts = 10000;
while($l = fgets(STDIN)){
if ( preg_match('/^(INSERT INTO .* VALUES) (.*);/',$l,$s) )
{
if ( $last != $s[1] || $count > $maxinserts )
{
if ( $count > $maxinserts ) // Limit the inserts
echo ";\n";
echo "$s[1] ";
$comma = '';
$last = $s[1];
$count = 0;
}
echo "$comma$s[2]";
$comma = ",\n";
} elseif ( $last != '' ) {
$last = '';
echo ";\n";
}
$count++;
}