Kết xuất cơ sở dữ liệu mysql vào bản sao lưu bản rõ (CSV) từ dòng lệnh


92

Tôi muốn tránh mysqldump vì nó xuất ra ở dạng chỉ thuận tiện cho mysql đọc. CSV có vẻ phổ biến hơn (một tệp cho mỗi bảng cũng được). Nhưng nếu có lợi thế cho mysqldump, tôi đều có tai. Ngoài ra, tôi muốn một cái gì đó mà tôi có thể chạy từ dòng lệnh (linux). Nếu đó là một tập lệnh mysql, thì các gợi ý về cách tạo một thứ như vậy sẽ rất hữu ích.


Câu trả lời:


140

Nếu bạn có thể xử lý từng bảng một và dữ liệu của bạn không phải là hệ nhị phân, hãy sử dụng -Btùy chọn đối với mysqllệnh. Với tùy chọn này, nó sẽ tạo các tệp TSV (được phân tách bằng tab) có thể nhập vào Excel, v.v., khá dễ dàng:

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

Ngoài ra, nếu bạn có quyền truy cập trực tiếp vào hệ thống tệp của máy chủ, hãy sử dụng hệ thống SELECT INTO OUTFILEcó thể tạo tệp CSV thực:

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

cảm ơn! "bảng" thứ hai của bạn phải là "cơ sở dữ liệu", phải không? không có tùy chọn nào cho CSV thay vì TSV mà bạn biết?
dreeves

duh - vâng, nó nên đọc 'cơ sở dữ liệu'. Không, không có tùy chọn nào cho CSV, đây là tùy chọn tốt nhất mà tôi biết mà không sử dụng 'select into outfile' tích hợp sẵn của MySQL, có thể thực hiện CSV, nhưng ghi các tệp trên máy chủ chứ không phải máy khách.
Alnitak

làm thế nào để buộc ghi đè lên tệp đầu ra?
JCm

11
Lưu ý rằng khi một đường dẫn tương đối (hoặc đơn giản là tên tệp) được cung cấp, tệp sẽ xuất hiện trong thư mục MYSQL của bạn, chứ không phải thư mục shell hiện tại của bạn (tức là nơi \. file.sqlđọc từ). Như vậy, tùy thuộc vào cài đặt của bạn, bạn có thể sẽ tìm thấy nó tại/var/lib/mysql/[db_name]/table.csv
Mala

32

Trong chính MySQL, bạn có thể chỉ định đầu ra CSV như:

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

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


2
Tôi dường như không thể tìm thấy tệp kết xuất trên thư mục mà tôi đã chỉ định, tại sao vậy?
JCm

@JCm nó được lưu trữ trên máy chủ
Alnitak

26

Bạn có thể kết xuất toàn bộ cơ sở dữ liệu trong một lần với mysqldump's --tabtùy chọn. Bạn cung cấp một đường dẫn thư mục và nó tạo một .sqltệp với CREATE TABLE DROP IF EXISTScú pháp và một .txttệp có nội dung, được phân tách bằng tab. Để tạo các tệp được phân tách bằng dấu phẩy, bạn có thể sử dụng các cách sau:

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

Đường dẫn đó cần phải được ghi bởi cả người dùng mysql và người dùng chạy lệnh, vì vậy để đơn giản, tôi khuyên bạn nên sử dụng chmod 777 /tmp/path_to_dump/trước.


1
Tôi tiếp tục quay lại câu trả lời này, đó chắc chắn là cách tốt nhất để xuất tất cả các bảng sang tệp được phân tách.
joevallender

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

Là người chủ: GRANT FILE ON *.* TO 'user1'@'localhost';- stackoverflow.com/a/15014385/1707015 . Trong trường hợp của tôi, tôi phải sử dụng /var/lib/mysql-files/(thay vì /tmp/), đặt người dùng thành mysql: mysql và đặt quyền thành 777 - stackoverflow.com/a/32737616/1707015 .
qräbnö

18

Tùy chọn select into outfile sẽ không hoạt động đối với tôi nhưng cách đường vòng dưới đây để chuyển tệp phân cách bằng tab qua SED đã làm được:

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

1
Lệnh này dẫn đến ký tự tđược thay thế bằng ", "trong tệp đầu ra. Không chính xác những gì tôi đang theo đuổi.
BrennanR

9

Đây là lệnh đơn giản nhất cho nó

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

Nếu có dấu phẩy trong giá trị cột thì chúng ta có thể tạo .tsv thay vì .csv bằng lệnh sau

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

Đối với CSV: nó hoạt động khi tôi chỉ cần dấu phẩy. mysql -hlocalhost -uroot -e 'select * from databaseName.tableNaame' | sed 's/\t/,/g' > /tmp/output.csv`

3

Nếu bạn thực sự cần một "Bản sao lưu" thì bạn cũng cần lược đồ cơ sở dữ liệu, như định nghĩa bảng, định nghĩa chế độ xem, thủ tục lưu trữ, v.v. Bản sao lưu cơ sở dữ liệu không chỉ là dữ liệu.

Giá trị của định dạng mysqldump để sao lưu cụ thể là nó rất DỄ DÀNG khi sử dụng nó để khôi phục cơ sở dữ liệu mysql. Một bản sao lưu không dễ dàng khôi phục sẽ kém hữu ích hơn nhiều. Nếu bạn đang tìm kiếm một phương pháp để sao lưu dữ liệu mysql một cách đáng tin cậy để bạn có thể khôi phục lại máy chủ mysql thì tôi nghĩ bạn nên gắn bó với công cụ mysqldump.

Mysql miễn phí và chạy trên nhiều nền tảng khác nhau. Thiết lập một máy chủ mysql mới mà tôi có thể khôi phục rất đơn giản. Tôi hoàn toàn không lo lắng về việc không thể thiết lập mysql để tôi có thể thực hiện khôi phục.

Tôi sẽ lo lắng hơn nhiều về việc sao lưu / khôi phục tùy chỉnh dựa trên một định dạng mỏng manh như csv / tsv không thành công. Bạn có chắc chắn rằng tất cả các dấu ngoặc kép, dấu phẩy hoặc các tab trong dữ liệu của bạn sẽ được thoát đúng cách và sau đó được phân tích cú pháp chính xác bằng công cụ khôi phục của bạn?

Nếu bạn đang tìm kiếm một phương pháp để trích xuất dữ liệu thì hãy xem một số câu trả lời khác.


cảm ơn, rất hữu ích! bạn đã thuyết phục tôi. Tuy nhiên, tôi có những lý do khác để muốn có một cách nhanh chóng để có được một kết xuất csv thông qua một lệnh dòng lệnh. tôi đang chờ đợi điều đó cho "câu trả lời được chấp nhận". (tho tôi có thể ghép nó lại với nhau vào thời điểm này từ các câu trả lời hiện tại, tôi đoán là tập lệnh mysql).
dreeves

Tôi có thể thấy rất nhiều giá trị khi có cả một bản sao lưu bằng cách sử dụng phương pháp gốc và cũng trích xuất cho các mục đích khác.
Zoredache

mk -llel-restore có thể khôi phục bản sao lưu CSV được tạo bằng mk -llel-dump, vì vậy bạn có thể tận dụng tối đa cả hai thế giới. Trên thực tế, mk -llel-restore hoạt động tốt hơn bằng cách đảm bảo mọi trình kích hoạt bạn đã xác định đều được khôi phục sau cùng.
Paul Dixon

3

Bạn có thể sử dụng tập lệnh dưới đây để lấy đầu ra cho tệp csv. Một tệp cho mỗi bảng có tiêu đề.

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

user là tên người dùng của bạn, password là mật khẩu nếu bạn không muốn tiếp tục nhập mật khẩu cho mỗi bảng và mydb là tên cơ sở dữ liệu.

Giải thích tập lệnh: Biểu thức đầu tiên trong sed, sẽ thay thế các tab bằng "," vì vậy bạn có các trường được đặt trong dấu ngoặc kép và được phân tách bằng dấu phẩy. Cái thứ hai chèn dấu ngoặc kép ở đầu và cái thứ ba chèn dấu ngoặc kép ở cuối. Và điều cuối cùng sẽ xử lý \ n.


Điều này chủ yếu đưa tôi đến nơi tôi cần đến nhưng thật ngạc nhiên khi chữ "t" được thay thế bằng dấu phẩy: stackoverflow.com/a/2610121/8400969
Michael

Và điều này cũng nên nói --skip-column-namestrong phiên bản mysql của tôi
Michael

2

Hãy xem mk -llel -dump là một phần của bộ công cụ maatkit hữu ích . Điều này có thể kết xuất các tệp được phân tách bằng dấu phẩy với tùy chọn --csv.

Điều này có thể thực hiện toàn bộ db của bạn mà không cần chỉ định các bảng riêng lẻ và bạn có thể chỉ định các nhóm bảng trong bảng sao lưu.

Lưu ý rằng nó cũng kết xuất các định nghĩa bảng, dạng xem và trình kích hoạt vào các tệp riêng biệt. Ngoài việc cung cấp một bản sao lưu hoàn chỉnh ở dạng dễ tiếp cận hơn, nó cũng có thể khôi phục ngay lập tức với mk -llel-restore


Đây có thể không phải là bản sao lưu lý tưởng nhưng hoàn toàn tuyệt vời để CHIA SẺ. Cảm ơn bạn!
atroon

maatkitdường như là một phần của percona toolkithiện tại, nhưng tôi không thể tìm thấy các công cụ tương ứng.
sjas

1

Câu trả lời PowerShell hai dòng:

# 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 = tên cơ sở dữ liệu của bạn

-e = truy vấn

-B = phân cách bằng tab


1

Nếu bạn muốn kết xuất toàn bộ db dưới dạng 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.