it-swarm.asia

هل من الممكن mysqldump مجموعة فرعية من قاعدة البيانات المطلوبة لإعادة إنتاج الاستعلام؟

الخلفية

أود تقديم مجموعة فرعية من قاعدة بياناتي المطلوبة لإعادة إنتاج استعلام select. هدفي هو جعل سير العمل الحسابي قابلاً للتكرار (كما في البحث القابل للتكرار ).

سؤال

هل هناك طريقة يمكنني فيها دمج عبارة التحديد هذه في برنامج نصي يفرغ البيانات المستعلم عنها في قاعدة بيانات جديدة ، بحيث يمكن تثبيت قاعدة البيانات على خادم mysql جديد ، وستعمل العبارة مع قاعدة البيانات الجديدة. يجب ألا تحتوي قاعدة البيانات الجديدة على سجلات بالإضافة إلى تلك التي تم استخدامها في الاستعلام.

Update: للتوضيح ، لست مهتمًا بتفريغ csv لنتائج الاستعلام. ما أريد القيام به هو تفريغ مجموعة قاعدة البيانات الفرعية بحيث يمكن تثبيتها على جهاز آخر ، ومن ثم يمكن استنساخ الاستعلام نفسه (وتعديله فيما يتعلق بمجموعة البيانات نفسها).

مثال

على سبيل المثال ، قد يستفسر تحليلي عن مجموعة فرعية من البيانات التي تتطلب سجلات من جداول متعددة (في هذا المثال 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 لديه الخيار - أين لتنفيذ جملة WHERE لجدول معين.

على الرغم من أنه من غير الممكن إجراء استعلام انضمام إلى mysqldump ، يمكنك تصدير صفوف معينة من كل جدول بحيث يتم تضمين كل صف يتم جلبه من كل جدول في الانضمام لاحقًا.

بالنسبة لاستعلامك المحدد ، ستحتاج إلى mysqldump ثلاث مرات:

أولاً ، mysqldump جميع صفوف الجدول 3 مع الاسم في ("fee" ، "fi" ، "fo" ، "fum"):

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

بعد ذلك ، mysqldump لجميع صفوف table2 التي تتطابق مع قيم table3_id من الخلية الأولى:

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

بعد ذلك ، mysqldump لجميع صفوف table1 التي لها قيم مطابقة table1_id من الخلية الثانية:

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

ملاحظة: بما أن الخلية الثانية والثالثة تتطلب استخدام أكثر من جدول واحد ، يجب استخدام - all-all-tables .

إنشاء قاعدة بياناتك الجديدة:

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

أخيرًا ، قم بتحميل mysqldumps الثلاثة في قاعدة بيانات أخرى وحاول الانضمام هناك في قاعدة البيانات الجديدة.

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

في عميل mysql ، قم بتشغيل استعلام الانضمام

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'); 

جربها !!!

تحذير: إذا لم تتم فهرستها بشكل صحيح ، فقد تستغرق الخلية الثانية والثالثة إلى الأبد !!!

تحسبًا لفهرسة الأعمدة التالية:

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

سأفترض أن id هو المفتاح الأساسي للجدول 3.

55
RolandoMySQLDBA

أود أن أعتبر باستخدام 'outfile' كجزء من SELECT بدلاً من mysqldump لحل هذه المشكلة. يمكنك إنتاج أي عبارة SELECT تريدها ، ثم إلحاق "INTO OUTFILE '/path/to/outfile.csv' ..." في النهاية بالتهيئة المناسبة لمخرجات نمط CSV. ثم يمكنك ببساطة استخدام شيء مثل بناء الجملة " LOAD DATA INFILE ..." لتحميل البيانات إلى موقع المخطط الجديد الخاص بك.

على سبيل المثال ، باستخدام SQL الخاصة بك:

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'
; 

ضع في اعتبارك أنك ستحتاج إلى مساحة تخزين متوفرة كافية على قسم القرص الهدف.

7
randomx

استخدام mysqldump يحتوي على - خيار الجداول يتيح لك تحديد الجداول المطلوب تفريغها. يتيح لك تحديد قائمة الجداول.

لا أعرف أي طريقة أسهل (مؤتمتة).

6
Richard

ما كان مفيدًا بالنسبة لي كان شيئًا مثل:

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

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

3
Ryan

هل جربت وظيفة الاقتباس في الخلية؟

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'); 

حفظ ما ورد أعلاه ، مثل query.sql

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

لقد كتبت نصًا صغيرًا لمشكلة مماثلة ، ومن هنا: 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";
?>

أي. لديك هذا الاستعلام :

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

لقد حصلت على هذا التفريغ :

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

في 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'); 

في سطر الأوامر:

mysqldump mydb table4 |gzip > table4.sql.gz

على خادم الوجهة ، قم بإعداد ~/.my.cnf

[client]
default-character-set=utf8

الاستيراد على الخادم الوجهة

zcat table4.sql.gz | mysql
1
velcrow