从命令行将mysql数据库转储到纯文本(CSV)备份中


92

我想避免mysqldump,因为它以仅便于mysql读取的形式输出。CSV似乎更通用(每个表一个文件就可以了)。但是,如果mysqldump有优势,我会很高兴。另外,我希望可以从命令行(linux)运行某些内容。如果那是mysql脚本,那么指向如何制作此类内容的指针将很有帮助。


Answers:


140

如果您一次可以处理表,并且您的数据不是二进制数据,请使用命令-B选项mysql。使用此选项,它将生成TSV(制表符分隔)文件,这些文件可以轻松导入Excel等文件中:

% echo 'SELECT * FROM table' | mysql -B -uxxx -pyyy database

或者,如果您可以直接访问服务器的文件系统,请使用SELECT INTO OUTFILE可以生成实际CSV文件的文件:

SELECT * INTO OUTFILE 'table.csv'
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n'
FROM table

谢谢!您的第二个“表”应该是“数据库”,对吧?没有CSV而不是您知道的TSV的选项?
dreeves

h-是的,它应该读为'database'。不,CSV没有选项,这是我不使用MySQL内置的“ select into outfile”(它可以执行CSV,但将文件写入服务器而不是客户端)时所了解的最好的信息。
Alnitak

如何在输出文件上强制覆盖?
JCm

11
请注意,当给出相对路径(或只是文件名)时,该文件将出现在您的MYSQL目录中,而不是您当前的shell目录(即\. file.sql读取位置)中。因此,根据您的安装,您可能会在/var/lib/mysql/[db_name]/table.csv
Mala 2016年


26

您可以一次性mysqldump's --tab选择转储整个数据库。您提供了一个目录路径,它创建了一个.sql具有CREATE TABLE DROP IF EXISTS语法的.txt文件和一个内容,制表符分隔的文件。要创建逗号分隔的文件,可以使用以下命令:

mysqldump --password  --fields-optionally-enclosed-by='"' --fields-terminated-by=',' --tab /tmp/path_to_dump/ database_name

该路径必须由mysql用户和运行该命令的用户均可写,因此为简单起见,我chmod 777 /tmp/path_to_dump/首先建议。


1
我一直回到这个答案,这绝对是将所有表导出到分隔文件的最佳方法。
joevallender

mysqldump: You must use option --tab with --fields-...
Marco Marsala

作为根:GRANT FILE ON *.* TO 'user1'@'localhost';- stackoverflow.com/a/15014385/1707015。在我的情况下,我不得不/var/lib/mysql-files/(而不是/tmp/)将用户设置为mysql:mysql,并将权限设置为777- 777-stackoverflow.com/a/32737616/1707015
–qräbnö

18

select into outfile选项对我不起作用,但是以下通过SED传递制表符分隔文件的回旋方式有效:

mysql -uusername -ppassword -e "SELECT * from tablename" dbname | sed 's/\t/","/g;s/^/"/;s/$/"/' > /path/to/file/filename.csv

1
此命令导致在输出文件中将字母t替换为字母", "。不完全是我的追求。
BrennanR

9

这是最简单的命令

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' | sed  's/\t/,/g' > output.csv

如果列值中有逗号,则可以使用以下命令生成.tsv而不是.csv

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' > output.csv

对于CSV:适用于我只需要逗号的地方。mysql -hlocalhost -uroot -e 'select * from databaseName.tableNaame' | sed 's/\t/,/g' > /tmp/output.csv`

3

如果确实需要“备份”,则还需要数据库架构,例如表定义,视图定义,存储过程等。数据库的备份不仅仅是数据。

专门用于备份的mysqldump格式的值是,使用它来还原mysql数据库非常容易。不容易还原的备份远没有那么有用。如果您正在寻找一种可靠地将mysql数据备份到的方法,以便可以还原到mysql服务器,那么我认为您应该坚持使用mysqldump工具。

Mysql是免费的,并且可以在许多不同的平台上运行。设置可以还原到的新mysql服务器非常简单。我完全不担心无法设置mysql,因此可以进行还原。

我会更加担心基于易碎格式(例如csv / tsv失败)的自定义备份/还原。您确定数据中的所有引号,逗号或制表符将被正确转义,然后被还原工具正确解析吗?

如果您正在寻找一种提取数据的方法,请参见其他答案。


谢谢,非常有帮助!你说服了我。我确实有其他原因想要通过命令行命令快速获取csv转储。我为此争取“可接受的答案”。(通过当前的答案,我可能会在此时将其拼凑在一起,我想带有一个mysql脚本)。
dreeves,2009年

在使用本机方法进行备份以及将其提取以用于其他目的时,我可以看到很多价值。
Zoredache

mk-parallel-restore可以还原使用mk-parallel转储创建的CSV备份,因此您可以兼得两者。实际上,mk-parallel-restore通过确保最后恢复您定义的任何触发器来做得更好。
保罗·迪克森

3

您可以使用以下脚本将输出获取到csv文件。每个表一个文件,带标题。

for tn in `mysql --batch --skip-page --skip-column-name --raw -uuser -ppassword -e"show tables from mydb"`
do 
mysql -uuser -ppassword mydb -B -e "select * from \`$tn\`;" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > $tn.csv
done

用户是您的用户名,如果您不想一直为每个表键入密码,则密码是密码,而mydb是数据库名称。

脚本说明:sed中的第一个表达式将用“,”替换制表符,因此您将字段括在双引号中并用逗号分隔。第二个在开头插入双引号,第三个在结尾插入双引号。最后一个负责\ n。


这主要带给我我需要去的地方,但是当字母“ t”被逗号替换时感到惊讶:stackoverflow.com/a/2610121/8400969
Michael

这也应该--skip-column-names在我的mysql版本中说
迈克尔

2

查看mk-parallel-dump,它是maatkit工具套件中一直有用的一部分。这可以使用--csv选项转储以逗号分隔的文件。

这样就可以完成整个数据库,而无需指定单个表,并且可以在backupset表中指定表组。

请注意,它还将表定义,视图和触发器转储到单独的文件中。除了以更通用的形式提供完整的备份外,还可以通过mk-parallel-restore立即恢复


这可能不是理想的备份,但是对于SHARING来说确实很棒。谢谢!
2011年

maatkit似乎是percona toolkit现在的一部分,但我找不到相应的工具。
sjas

1

两行PowerShell答案:

# Store in variable
$Global:csv = (mysql -uroot -p -hlocalhost -Ddatabase_name -B -e "SELECT * FROM some_table") `
| ConvertFrom-Csv -Delimiter "`t"

# Out to csv
$Global:csv | Export-Csv "C:\temp\file.csv" -NoTypeInformation

Boom-Bata-Boom

-D =您的数据库名称

-e =查询

-B =制表符分隔


1

如果要将整个数据库转储为csv

#!/bin/bash

host=hostname
uname=username
pass=password

port=portnr
db=db_name
s3_url=s3://bxb2-anl-analyzed-pue2/bxb_ump/db_dump/



DATE=`date +%Y%m%d`
rm -rf $DATE

echo 'show tables' | mysql -B -h${host} -u${uname} -p${pass} -P${port} ${db} > tables.txt
awk 'NR>1' tables.txt > tables_new.txt

while IFS= read -r line
do
  mkdir -p $DATE/$line
  echo "select * from $line" | mysql -B -h"${host}" -u"${uname}" -p"${pass}" -P"${port}" "${db}" > $DATE/$line/dump.tsv
done < tables_new.txt

touch $DATE/$DATE.fin


rm -rf tables_new.txt tables.txt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.