Dies wurde einige Male gefragt, aber ich kann keine Lösung für mein Problem finden. Bei der Verwendung von mysqldump, dem integrierten Werkzeug für das MySQL Workbench-Verwaltungstool, erhalte ich beim Ablegen einer Datenbank mit erweiterten Inserts gewaltige lange Datenzeilen. Ich verstehe, warum dies so ist, da es die Einfügungen beschleunigt, indem die Daten als ein Befehl eingefügt werden (insbesondere bei InnoDB). Die Formatierung macht es jedoch WIRKLICH schwierig, die Daten in einer Dump-Datei zu betrachten oder zwei Dateien mit einem Vergleichstool zu vergleichen wenn Sie sie in der Versionskontrolle usw. speichern. In meinem Fall speichere ich sie in der Versionskontrolle, da wir die Dump-Dateien verwenden, um den Überblick über unsere Integrationstestdatenbank zu behalten.
Jetzt weiß ich, dass ich erweiterte Einfügungen deaktivieren kann. Daher bekomme ich pro Zeile eine Einfügung. Diese Funktion funktioniert, aber jedes Mal, wenn Sie die Dump-Datei wiederherstellen, wird sie langsamer.
Mein Kernproblem ist, dass das OLD-Tool (MySQL Administrator), das wir beim Ablegen einer Datei verwendet haben, im Grunde das Gleiche tut, jedoch FORMATS die INSERT-Anweisung, um eine Einfügung pro Zeile einzufügen, während gleichzeitig Masseneinfügungen ausgeführt werden. Also stattdessen:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES (887,'0.0000'),191607,'1.0300');
du bekommst das:
INSERT INTO `coupon_gv_customer` (`customer_id`,`amount`) VALUES
(887,'0.0000'),
(191607,'1.0300');
Egal welche Optionen ich versuche, es scheint keine Möglichkeit zu geben, eine Mülldeponie wie diese zu bekommen, was wirklich das Beste aus beiden Welten ist. Ja, es braucht etwas mehr Platz, aber in Situationen, in denen Sie einen Menschen zum Lesen der Dateien benötigen, ist es VIEL nützlicher.
Fehlt mir etwas und es gibt eine Möglichkeit, dies mit MySQLDump zu tun, oder sind wir alle rückwärts gegangen und diese Funktion in dem alten (jetzt veralteten) MySQL-Administrator-Tool ist nicht mehr verfügbar?
Bei dem standardmäßigen mysqldump-Format generiert jeder Datensatz einen einzelnen INSERT-Befehl in der dump-Datei (d. H. Die sql-Datei), jeder in seiner eigenen Zeile. Dies ist perfekt für die Quellensteuerung (z. B. SVN, GIT usw.), da die Differenz- und Delta-Auflösung viel feiner werden und letztendlich ein effizienterer Quellensteuerungsprozess erzielt wird. Die Ausführung all dieser INSERT-Abfragen kann jedoch bei Tabellen mit beträchtlicher Größe die Wiederherstellung aus der SQL-Datei möglicherweise zu langsam machen.
Mit der Option --extended-insert wird das mehrfache INSERT-Problem behoben, indem alle Datensätze in einem einzigen INSERT-Befehl in einer einzigen Zeile der abgelegten SQL-Datei zusammengefasst werden. Der Source-Control-Prozess wird jedoch sehr ineffizient. Der gesamte Tabelleninhalt wird in einer einzigen Zeile in der SQL-Datei dargestellt. Wenn sich ein einzelnes Zeichen irgendwo in dieser Tabelle ändert, kennzeichnet die Quellcodeverwaltung die gesamte Zeile (d. H. Die gesamte Tabelle) als Delta zwischen den Versionen. Bei großen Tabellen werden dadurch viele Vorteile des Einsatzes eines formalen Quellcodeverwaltungssystems zunichte gemacht.
Idealerweise möchten wir für eine effiziente Datenbankwiederherstellung in der SQL-Datei jede Tabelle durch eine einzelne INSERT-Datei darstellen. Für einen effizienten Quellcodeverwaltungsprozess möchten wir in der SQL-Datei, dass sich jeder Datensatz in diesem INSERT-Befehl in einer eigenen Zeile befindet.
Meine Lösung hierfür ist das folgende Backup-Skript:
#!/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
Das Ergebnis ist ein SQL-Datei-INSERT-Befehlsformat, das folgendermaßen aussieht:
INSERT INTO `mytable` VALUES
(r1c1value, r1c2value, r1c3value),
(r2c1value, r2c2value, r2c3value),
(r3c1value, r3c2value, r3c3value);
Einige Notizen:
Verwenden Sie die folgende Option: --skip-extended-insert
Es hat für mich funktioniert.
Wie andere bereits sagten, verwenden Sie sed zum Ersetzen von "), (" ist nicht sicher, da dies als Inhalt in der Datenbank erscheinen kann.). Dies kann jedoch folgendermaßen geschehen: folgende:
$ 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
sie können auch "sed -i" verwenden, um die In-Line zu ersetzen.
Folgendes tut dieser Code:
Hoffe das hilft
Wie wäre es, wenn Sie den Speicherauszug in einer CSV-Datei mit mysqldump speichern, indem Sie die --tab
-Option wie folgt verwenden?
mysqldump --tab=/path/to/serverlocaldir --single-transaction <database> table_a
Dies erzeugt zwei Dateien:
table_a.sql
, der nur die Anweisung zum Erstellen der Tabelle enthält; undtable_a.txt
, der durch Tabulatoren getrennte Daten enthält.Sie können Ihre Tabelle über LOAD DATA
wiederherstellen:
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_a FIELDS TERMINATED BY '\t' ...
LOAD DATA ist normalerweise 20 Mal schneller als mit INSERT-Anweisungen.
Wenn Sie Ihre Daten in einer anderen Tabelle wiederherstellen müssen (z. B. zu Überprüfungs- oder Testzwecken), können Sie eine "Spiegeltabelle" erstellen:
CREATE TABLE table_for_test LIKE table_a;
Laden Sie dann die CSV in die neue Tabelle:
LOAD DATA INFILE '/path/to/serverlocaldir/table_a.txt'
INTO TABLE table_for_test FIELDS TERMINATED BY '\t' ...
Eine CSV-Datei ist am einfachsten für Vergleiche oder für den Blick in die Umgebung oder für technische Benutzer ohne SQL, die gängige Tools wie Excel
, Access
oder Befehlszeile verwenden (diff
, comm
usw.)
Ich fürchte, das wird nicht möglich sein. Im alten MySQL-Administrator habe ich den Code zum Ablegen von db-Objekten geschrieben, der völlig unabhängig von dem mysqldump-Tool war und daher eine Reihe zusätzlicher Optionen (wie diese Formatierung oder Fortschrittsrückmeldung) bot. In MySQL Workbench wurde beschlossen, stattdessen das Tool mysqldump zu verwenden, das neben dem Zurücksetzen in einigen Punkten und dem Erzeugen von Versionsproblemen den Vorteil hat, immer auf dem neuesten Stand zu bleiben.
Die kurze Antwort lautet also: Mit mysqldump ist derzeit keine Formatierung möglich.
Ich fand dieses Tool sehr hilfreich für den Umgang mit erweiterten Einfügungen: http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts.html
Es analysiert die mysqldump-Ausgabe und fügt nach jedem Datensatz Zeilenumbrüche ein, verwendet jedoch immer die schnelleren erweiterten Einfügungen. Im Gegensatz zu einem sed-Skript sollte die Gefahr bestehen, dass Zeilen an der falschen Stelle gebrochen werden, wenn der Regex innerhalb einer Zeichenfolge übereinstimmt.
Versuche dies:
mysqldump -c -t --add-drop-table=FALSE --skip-extended-insert -uroot -p<Password> databaseName tableName >c:\path\nameDumpFile.sql
Ich mochte die Lösung von Ace.Di mit sed, bis ich diese Fehlermeldung erhielt: Sed: Speicher konnte nicht erneut zugewiesen werden
Also musste ich ein kleines PHP Skript schreiben
mysqldump -u my_db_user -p -h 127.0.0.1 --skip-extended-insert my_database | php mysqlconcatinserts.php > db.sql
Das Skript PHP generiert auch für 10.000 Zeilen ein neues INSERT, um Speicherprobleme zu vermeiden.
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++;
}