ถ่ายโอนฐานข้อมูล mysql ไปยังข้อมูลสำรองข้อความธรรมดา (CSV) จากบรรทัดคำสั่ง


93

ฉันต้องการหลีกเลี่ยง mysqldump เนื่องจากเอาต์พุตจะอยู่ในรูปแบบที่สะดวกสำหรับ mysql ในการอ่าน CSV ดูเป็นสากลมากขึ้น (ใช้ได้หนึ่งไฟล์ต่อตาราง) แต่ถ้ามีข้อดีคือ mysqldump ฉันก็หูผึ่ง นอกจากนี้ฉันต้องการบางสิ่งที่ฉันสามารถเรียกใช้จากบรรทัดคำสั่ง (linux) หากนั่นเป็นสคริปต์ mysql คำแนะนำวิธีสร้างสิ่งนั้นจะเป็นประโยชน์


1
อาจซ้ำกันได้ของHow to output MySQL query results in csv format?
เบ็น

คำตอบ:


141

หากคุณสามารถรับมือกับตารางต่อเวลาได้และข้อมูลของคุณไม่ใช่ไบนารีให้ใช้-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

duh - ใช่มันควรจะอ่าน 'ฐานข้อมูล' ไม่ไม่มีตัวเลือกสำหรับ CSV นี่เป็นวิธีที่ดีที่สุดที่ฉันรู้จักโดยไม่ต้องใช้ 'select into outfile' ในตัวของ MySQL ซึ่งสามารถทำ CSV ได้ แต่เขียนไฟล์บนเซิร์ฟเวอร์ไม่ใช่ไคลเอนต์
Alnitak

วิธีบังคับเขียนทับบนไฟล์เอาต์พุต
JCm

11
โปรดทราบว่าเมื่อกำหนดพา ธ สัมพัทธ์ (หรือเพียงแค่ชื่อไฟล์) ไฟล์จะปรากฏในไดเร็กทอรี MYSQL ของคุณไม่ใช่ไดเร็กทอรีเชลล์ปัจจุบันของคุณ (เช่นที่\. file.sqlอ่านจาก) ดังนั้นขึ้นอยู่กับการติดตั้งของคุณคุณจะพบได้ที่/var/lib/mysql/[db_name]/table.csv
Mala

32

ใน MySQL คุณสามารถระบุเอาต์พุต CSV เช่น:

SELECT order_id,product_name,qty
FROM orders
INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

จากhttp://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/


2
ดูเหมือนว่าฉันไม่พบไฟล์ที่ถูกทิ้งในไดเร็กทอรีที่ฉันระบุเหตุใดจึงเป็นเช่นนั้น
JCm

@JCm ทิ้งบนเซิร์ฟเวอร์
Alnitak

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 - stackoverflow.com/a/32737616/1707015
qräbnö

18

ตัวเลือกเลือกลงในไฟล์ไม่ทำงานสำหรับฉัน แต่วิธีการอ้อมด้านล่างของการวางไฟล์ที่คั่นด้วยแท็บผ่าน 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 ล้มเหลว คุณแน่ใจหรือไม่ว่าเครื่องหมายคำพูดจุลภาคหรือแท็บทั้งหมดที่อยู่ในข้อมูลของคุณจะได้รับการ Escape อย่างถูกต้องจากนั้นเครื่องมือเรียกคืนจะแยกวิเคราะห์อย่างถูกต้อง

หากคุณกำลังมองหาวิธีการดึงข้อมูลให้ดูคำตอบอื่น ๆ


ขอบคุณมีประโยชน์มาก! คุณทำให้ฉันเชื่อมั่น ฉันมีเหตุผลอื่นที่ต้องการวิธีที่รวดเร็วในการรับไฟล์ csv ผ่านคำสั่งบรรทัดคำสั่ง ฉันถือเอาสิ่งนั้นสำหรับ "คำตอบที่ยอมรับ" (ฉันอาจจะรวมเข้าด้วยกัน ณ จุดนี้จากคำตอบปัจจุบันฉันเดาว่าด้วยสคริปต์ mysql)
เริ่ม

ฉันเห็นคุณค่ามากมายในการมีทั้งการสำรองข้อมูลโดยใช้วิธีเนทีฟและการแยกเพื่อวัตถุประสงค์อื่น
Zoredache

mk-parallel-restore สามารถคืนค่าการสำรองข้อมูล CSV ที่สร้างด้วย mk-parallel Dump เพื่อให้คุณได้รับสิ่งที่ดีที่สุดจากทั้งสองโลก ในความเป็นจริง mk-parallel-restore ทำงานได้ดีกว่าโดยตรวจสอบให้แน่ใจว่าทริกเกอร์ใด ๆ ที่คุณกำหนดไว้จะถูกเรียกคืนล่าสุด
Paul Dixon

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 เวอร์ชันของฉันเช่นกัน
Michael

2

ตรวจสอบmk ขนานการถ่ายโอนข้อมูลซึ่งเป็นส่วนหนึ่งของที่เคยมีประโยชน์ในตัว maatkit ของเครื่องมือ ซึ่งสามารถถ่ายโอนไฟล์ที่คั่นด้วยเครื่องหมายจุลภาคด้วยตัวเลือก --csv

สิ่งนี้สามารถทำฐานข้อมูลทั้งหมดของคุณโดยไม่ต้องระบุแต่ละตารางและคุณสามารถระบุกลุ่มของตารางในตารางชุดสำรองได้

โปรดทราบว่ายังทิ้งนิยามตารางมุมมองและทริกเกอร์ลงในไฟล์แยกต่างหาก นอกจากนี้การสำรองข้อมูลที่สมบูรณ์ในรูปแบบที่สามารถเข้าถึงได้ในระดับสากลมากขึ้นแล้วยังสามารถเรียกคืนได้ทันทีด้วยmk-parallel-restore


นี่อาจไม่ใช่การสำรองข้อมูลในอุดมคติแต่เหมาะอย่างยิ่งสำหรับการแชร์ ขอบคุณ!
atroon

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

บูมบาตะบูม

-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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.