it-swarm.asia

Apakah mungkin untuk mysqldump bagian dari database yang diperlukan untuk mereproduksi kueri?

Latar Belakang

Saya ingin memberikan subset dari basis data saya yang diperlukan untuk mereproduksi permintaan select. Tujuan saya adalah membuat alur kerja komputer saya dapat direproduksi (seperti dalam penelitian yang dapat direproduksi ).

Pertanyaan

Apakah ada cara saya bisa memasukkan pernyataan pilih ini ke dalam skrip yang membuang data yang diminta ke dalam database baru, sehingga database dapat diinstal pada server mysql baru, dan pernyataan itu akan bekerja dengan database baru. Basis data baru tidak boleh berisi catatan selain dari yang telah digunakan dalam kueri.

Perbarui: Untuk klarifikasi, saya tidak tertarik dengan dump csv hasil pencarian. Apa yang saya harus dapat lakukan adalah membuang subset database sehingga dapat diinstal pada komputer lain, dan kemudian permintaan itu sendiri dapat direproduksi (dan dapat dimodifikasi sehubungan dengan dataset yang sama).

Contoh

Misalnya, analisis saya mungkin meminta sebagian data yang membutuhkan rekaman dari beberapa tabel (dalam contoh ini 3):

select table1.id, table1.level, table2.name, table2.level 
       from table1 join table2 on table1.id = table2.table1_id 
       join table3 on table3.id = table2.table3_id
       where table3.name in ('fee', 'fi', 'fo', 'fum'); 
38
David LeBauer

mysqldump memiliki opsi - where untuk mengeksekusi klausa WHERE untuk tabel yang diberikan.

Meskipun mysqldump mysqldump tidak dapat digabung, Anda dapat mengekspor baris tertentu dari setiap tabel sehingga setiap baris yang diambil dari setiap tabel akan terlibat dalam gabungan di kemudian hari.

Untuk permintaan yang Anda berikan, Anda harus melakukan mysqldump tiga kali:

Pertama, mysqldump semua baris table3 dengan nama dalam ('fee', 'fi', 'fo', 'fum'):

mysqldump -u... -p... --where="name in ('fee','fi','fo','fum')" mydb table3 > table3.sql

Selanjutnya, mysqldump semua baris table2 yang memiliki nilai table3_id yang cocok dari mysqldump pertama:

mysqldump -u... -p... --lock-all-tables --where="table3_id in (select id from table3 where name in ('fee','fi','fo','fum'))" mydb table2 > table2.sql

Kemudian, mysqldump semua baris table1 yang memiliki nilai table1_id yang cocok dari mysqldump kedua:

mysqldump -u... -p... --lock-all-tables --where="id in (select table1_id from table2 where table3_id in (select id from table3 where name in ('fee','fi','fo','fum')))" mydb table1 > table1.sql

Catatan: Karena mysqldumps kedua dan ketiga membutuhkan lebih dari satu tabel, --lock-all-tables harus digunakan .

Buat database baru Anda:

mysqladmin -u... -p... mysqladmin create newdb

Akhirnya, muat ketiga mysqldumps ke database lain dan coba gabung di sana di database baru.

mysql -u... -p... -D newdb < table1.sql
mysql -u... -p... -D newdb < table2.sql
mysql -u... -p... -D newdb < table3.sql

Di klien mysql, jalankan kueri bergabung Anda

mysql> use newdb
mysql> select table1.id, table1.level, table2.name, table2.level 
       from table1 join table2 on table1.id = table2.table1_id 
       join table3 on table3.id = table2.table3_id
       where table3.name in ('fee', 'fi', 'fo', 'fum'); 

Cobalah !!!

PERINGATAN: Jika tidak diindeks dengan benar, mysqldumps kedua dan ketiga mungkin berlangsung selamanya !!!

Untuk jaga-jaga, indeks kolom berikut:

ALTER TABLE table2 ADD INDEX (table1_id);
ALTER TABLE table2 ADD INDEX (table3_id);
ALTER TABLE table3 ADD INDEX (name,id);

Saya akan menganggap id adalah kunci utama table3.

55
RolandoMySQLDBA

Saya akan mempertimbangkan menggunakan 'outfile' sebagai bagian dari SELECT Anda, bukan mysqldump untuk menyelesaikan masalah ini. Anda dapat menghasilkan pernyataan SELECT apa pun yang Anda inginkan, kemudian menambahkan "INTO OUTFILE '/path/to/outfile.csv' ..." di akhir dengan konfigurasi yang sesuai untuk output gaya CSV. Maka Anda cukup menggunakan sesuatu seperti sintaks ' LOAD DATA ...' untuk memuat data ke lokasi skema baru Anda.

Misalnya, menggunakan SQL Anda:

select table1.id, table1.level, table2.name, table2.level 
       from table1 join table2 on table1.id = table2.table1_id 
       join table3 on table3.id = table2.table3_id
       where table3.name in ('fee', 'fi', 'fo', 'fum')
INTO OUTFILE '/tmp/fee-fi-fo-fum.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
; 

Ingatlah bahwa Anda membutuhkan ruang penyimpanan yang cukup di partisi disk target.

7
randomx

Utilitas mysqldump memiliki opsi - tables yang memungkinkan Anda menentukan tabel mana yang akan dibuang. Ini memungkinkan Anda menentukan daftar tabel.

Saya tidak tahu cara yang lebih mudah (otomatis).

6
Richard

Apa yang bermanfaat bagi saya adalah sesuatu seperti:

mysqldump -u db_user -p db_name table_name --no_create_info \
--lock-all-tables --where 'id in (SELECT tn.id FROM table_name AS tn \
JOIN related_table AS rt ON tn.related_table_id = rt.id \
WHERE rt.some_field = 1)' > data.sql

Dari http://krosinski.blogspot.com/2012/12/using-table-join-with-mysqldump.html

3
Ryan

Sudahkah Anda mencoba fungsi quote di mysql?

SELECT CONCAT("insert into table4(id,level,name,levelt2) VALUES(",   quote(table1.id),   ",",    quote(table1.level),   ",",    quote(table2.name),   ",",    quote(table2.level),    ");") as q
       from table1 join table2 on table1.id = table2.table1_id 
       join table3 on table3.id = table2.table3_id
       where table3.name in ('fee', 'fi', 'fo', 'fum'); 

simpan di atas, sebagai query.sql

cat query.sql|mysql --skip-column-names --raw > table4.sql
2
velcrow

saya menulis skrip kecil untuk masalah yang sama, ini dia: https://github.com/digitalist/mysql_slice

include ('queryDumper.php');


$exampleQuery="select * from information_schema.columns c1 
left join information_schema.columns c2 on 1=1 limit 1";

//define credentials
$exampleMysqli = new mysqli($Host, $user, $password, $database);
$exampleResult=$exampleMysqli->query($exampleQuery);

//if  mysqlnd (native driver installed), otherwise use wrapper
$exampleData=fetchAll($exampleResult);
$exampleMeta=$exampleResult->fetch_fields();

/*
 * field content removal options
 * column name => function name in queryDumper.php, namespace QueryDumperHelpers
 * 
 * */

$forbiddenFields=array(
'password'=>'replacePassword', //change password -> md5("password")
'login'=>'replaceLogin', //change login [email protected] -> [email protected]
'comment'=>'sanitizeComment' //lorem ipsum or 
);


//get tables dump
$dump=(\queryDumper\dump($exampleData, $exampleMeta, $forbiddenFields));



$dropDatabase=true; //default false
$dropTable=true; //default false

$dbAndTablesCreationDump=\QueryDumperDatabaseAndTables\dump($exampleMysqli,$exampleMeta, $dropDatabase, $dropTable);

$databases=$dbAndTablesCreationDump['databases'];
$tables=$dbAndTablesCreationDump['tables'];
$eol=";\n\n";
echo implode($eol, $databases)."\n";
echo implode($eol, $tables).";\n";
echo "\n";

//consider using array_unique($dump) before imploding
echo implode("\n\n", $dump);
echo "\n";
?>

yaitu. Anda memiliki kueri ini :

SELECT * FROM employees.employees e1 
LEFT JOIN employees.employees e2 ON 1=1 
LIMIT 1; 

Anda mendapatkan dump ini :

DROP DATABASE `employees`;

CREATE DATABASE `employees`;
CREATE TABLE `employees` ( /* creation code */ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT IGNORE INTO `employees`.`employees` VALUES ("10001","1953-09-02","Georgi","Facello","M","1986-06-26");

INSERT IGNORE INTO `employees`.`employees` VALUES ("10001","1953-09-02","Georgi","Facello","M","1986-06-26");
1
digitalist

Di MySQL:

SHOW CREATE TABLE table1; -- use these two create statements
SHOW CREATE TABLE table2; -- to design table4's create statement
CREATE TABLE table4( .... );
INSERT INTO table4(id,level,name,levelt2)
SELECT table1.id, table1.level, table2.name, table2.level 
   from table1 join table2 on table1.id = table2.table1_id 
   join table3 on table3.id = table2.table3_id
   where table3.name in ('fee', 'fi', 'fo', 'fum'); 

Di Baris Perintah:

mysqldump mydb table4 |gzip > table4.sql.gz

Di server tujuan Anda, setup ~/.my.cnf

[client]
default-character-set=utf8

Impor di server tujuan

zcat table4.sql.gz | mysql
1
velcrow