كيف يمكنني إعادة تسمية قاعدة بيانات MySQL بسرعة (تغيير اسم المخطط)؟

StackOverflow https://stackoverflow.com/questions/67093

  •  09-06-2019
  •  | 
  •  

سؤال

دليل MySQL في ماي إس كيو إل يغطي هذا.

عادةً ما أقوم بتفريغ قاعدة البيانات وإعادة استيرادها باسم جديد.هذا ليس خيارًا لقواعد البيانات الكبيرة جدًا.فيما يبدو RENAME {DATABASE | SCHEMA} db_name TO new_db_name; يفعل أشياء سيئة، ولا يوجد إلا في عدد قليل من الإصدارات، وهو فكرة سيئة بشكل عام.

هذا يحتاج إلى العمل مع InnoDB, ، الذي يخزن الأشياء بشكل مختلف تمامًا عن MyISAM.

هل كانت مفيدة؟

المحلول

بالنسبة إلى InnoDB، يبدو أن ما يلي يعمل:أنشئ قاعدة البيانات الفارغة الجديدة، ثم أعد تسمية كل جدول بدوره إلى قاعدة البيانات الجديدة:

RENAME TABLE old_db.table TO new_db.table;

سوف تحتاج إلى ضبط الأذونات بعد ذلك.

للبرمجة النصية في الصدفة، يمكنك استخدام أي مما يلي:

mysql -u username -ppassword old_db -sNe 'show tables' | while read table; \ 
    do mysql -u username -ppassword -sNe "rename table old_db.$table to new_db.$table"; done

أو

for table in `mysql -u root -ppassword -s -N -e "use old_db;show tables from old_db;"`; do mysql -u root -ppassword -s -N -e "use old_db;rename table old_db.$table to new_db.$table;"; done;

ملحوظات:

  • ليس هناك مسافة بين الخيار -p وكلمة المرور.إذا لم تكن قاعدة البيانات الخاصة بك تحتوي على كلمة مرور، فقم بإزالة ملف -u username -ppassword جزء.
  • إذا كان هناك مشغل في بعض الجداول، فلا يمكن نقله إلى قاعدة بيانات أخرى باستخدام الطريقة المذكورة أعلاه (سوف ينتج عن ذلك Trigger in wrong schema خطأ).إذا كان الأمر كذلك، فاستخدم طريقة تقليدية لاستنساخ قاعدة بيانات ثم قم بإسقاط القاعدة القديمة:

    mysqldump old_db | mysql new_db

  • إذا كان لديك إجراءات مخزنة، يمكنك نسخها بعد ذلك:

    mysqldump -R old_db | mysql new_db

نصائح أخرى

استخدم هذه الأوامر البسيطة القليلة:

mysqldump -u username -p -v olddatabase > olddbdump.sql
mysqladmin -u username -p create newdatabase
mysql -u username -p newdatabase < olddbdump.sql

أو لتقليل عمليات الإدخال/الإخراج، استخدم ما يلي كما اقترح @Pablo Marin-Garcia:

mysqladmin -u username -p create newdatabase
mysqldump -u username -v olddatabase -p | mysql -u username -p -D newdatabase

أعتقد أن الحل أبسط وقد اقترحه بعض المطورين.لدى phpMyAdmin عملية لهذا الغرض.

من phpMyAdmin، حدد قاعدة البيانات التي تريد تحديدها.يوجد في علامات التبويب قسم يسمى "العمليات"، انتقل إلى قسم إعادة التسمية.هذا كل شئ.

فهو يقوم، كما اقترح الكثيرون، بإنشاء قاعدة بيانات جديدة بالاسم الجديد، وتفريغ جميع جداول قاعدة البيانات القديمة في قاعدة البيانات الجديدة وإسقاط قاعدة البيانات القديمة.

Enter image description here

يمكنك استخدام SQL لإنشاء برنامج نصي SQL لنقل كل جدول في قاعدة البيانات المصدر إلى قاعدة البيانات الوجهة.

يجب عليك إنشاء قاعدة البيانات الوجهة قبل تشغيل البرنامج النصي الذي تم إنشاؤه من الأمر.

يمكنك استخدام أي من هذين النصين (اقترحت في الأصل الأول وقام شخص ما "بتحسين" إجابتي لاستخدامه GROUP_CONCAT.اختر ما يناسبك، لكني أفضل الأصل):

SELECT CONCAT('RENAME TABLE $1.', table_name, ' TO $2.', table_name, '; ')
FROM information_schema.TABLES 
WHERE table_schema='$1';

أو

SELECT GROUP_CONCAT('RENAME TABLE $1.', table_name, ' TO $2.', table_name SEPARATOR '; ')
FROM information_schema.TABLES 
WHERE table_schema='$1';

(1 دولار و 2 دولار هما المصدر والهدف على التوالي)

سيؤدي هذا إلى إنشاء أمر SQL الذي سيتعين عليك تشغيله بعد ذلك.

لاحظ أن GROUP_CONCAT له حد افتراضي للطول يمكن تجاوزه بالنسبة لقواعد البيانات التي تحتوي على عدد كبير من الجداول.يمكنك تغيير هذا الحد عن طريق التشغيل SET SESSION group_concat_max_len = 100000000; (أو أي عدد كبير آخر).

محاكاة المفقودين RENAME DATABASE الأمر في MySQL:

  1. إنشاء قاعدة بيانات جديدة
  2. قم بإنشاء استعلامات إعادة التسمية باستخدام:

    SELECT CONCAT('RENAME TABLE ',table_schema,'.',table_name,
        ' TO ','new_schema.',table_name,';')
    FROM information_schema.TABLES
    WHERE table_schema LIKE 'old_schema';
    
  3. قم بتشغيل هذا الإخراج

  4. حذف قاعدة البيانات القديمة

تم أخذه من محاكاة أمر إعادة تسمية قاعدة البيانات المفقود في MySQL.

ثلاثة خيارات:

  1. قم بإنشاء قاعدة البيانات الجديدة، وقم بإسقاط الخادم، وانقل الملفات من مجلد قاعدة بيانات إلى آخر، وأعد تشغيل الخادم.لاحظ أن هذا لن يعمل إلا إذا كانت جميع جداولك هي MyISAM.

  2. قم بإنشاء قاعدة بيانات جديدة، استخدم CREATE TABLE ...عبارات مثل، ثم استخدم INSERT ...اختر * من البيانات.

  3. استخدم mysqldump وأعد التحميل باستخدام هذا الملف.

الطريقة البسيطة

التغيير إلى دليل قاعدة البيانات:

cd /var/lib/mysql/

قم بإيقاف تشغيل MySQL...هذا مهم!

/etc/init.d/mysql stop

حسنًا، هذه الطريقة لا تعمل مع قواعد بيانات InnoDB أو BDB.

إعادة تسمية قاعدة البيانات:

mv old-name new-name

...او الطاولة...

cd database/

mv old-name.frm new-name.frm

mv old-name.MYD new-name.MYD

mv old-name.MYI new-name.MYI

أعد تشغيل MySQL

/etc/init.d/mysql start

منتهي...

حسنًا، هذه الطريقة لا تعمل مع قواعد بيانات InnoDB أو BDB.في هذه الحالة عليك تفريغ قاعدة البيانات وإعادة استيرادها.

لقد عثرت مؤخرًا على طريقة رائعة جدًا للقيام بذلك، وهي تعمل مع MyISAM وInnoDB وهي سريعة جدًا:

RENAME TABLE old_db.table TO new_db.table;

لا أذكر أين قرأتها ولكن الفضل يعود إلى شخص آخر وليس أنا.

يمكنك استخدام برنامج Shell النصي هذا:

مرجع: كيفية إعادة تسمية قاعدة بيانات MySQL؟

#!/bin/bash
set -e # terminate execution on command failure

mysqlconn="mysql -u root -proot"
olddb=$1
newdb=$2
$mysqlconn -e "CREATE DATABASE $newdb"
params=$($mysqlconn -N -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \
                           WHERE table_schema='$olddb'")
for name in $params; do
      $mysqlconn -e "RENAME TABLE $olddb.$name to $newdb.$name";
done;
$mysqlconn -e "DROP DATABASE $olddb"

انها تعمل:

$ sh rename_database.sh oldname newname

هذا ما أستخدمه:

$ mysqldump -u root -p olddb >~/olddb.sql
$ mysql -u root -p
mysql> create database newdb;
mysql> use newdb
mysql> source ~/olddb.sql
mysql> drop database olddb;

أبسط طريقة مقاومة للرصاص والخداع للقيام بذلك مكتمل إعادة تسمية (بما في ذلك إسقاط قاعدة البيانات القديمة في النهاية بحيث تكون إعادة تسمية وليست نسخة):

mysqladmin -uroot -pmypassword create newdbname
mysqldump -uroot -pmypassword --routines olddbname | mysql -uroot -pmypassword newdbname
mysqladmin -uroot -pmypassword drop olddbname

خطوات:

  1. انسخ الأسطر إلى المفكرة.
  2. استبدل جميع المراجع إلى "olddbname"، و"newdbname"، و"mypassword" (+ اختياريًا "root") بما يعادلها.
  3. قم بالتنفيذ واحدًا تلو الآخر في سطر الأوامر (أدخل "y" عند المطالبة بذلك).

لا يدعم MySQL إعادة تسمية قاعدة البيانات من خلال واجهة الأوامر الخاصة بها في الوقت الحالي، ولكن يمكنك إعادة تسمية قاعدة البيانات إذا كان لديك حق الوصول إلى الدليل الذي يقوم MySQL بتخزين قواعد بياناته فيه.بالنسبة لعمليات تثبيت MySQL الافتراضية، يكون هذا عادةً في دليل البيانات ضمن الدليل الذي تم تثبيت MySQL فيه.حدد اسم قاعدة البيانات التي تريد إعادة تسميتها ضمن دليل البيانات وأعد تسميتها.قد تؤدي إعادة تسمية الدليل إلى حدوث بعض مشكلات الأذونات.كن حذرا.

ملحوظة: يجب عليك إيقاف MySQL قبل أن تتمكن من إعادة تسمية قاعدة البيانات

أوصي بإنشاء قاعدة بيانات جديدة (باستخدام الاسم الذي تريده) وتصدير/استيراد البيانات التي تحتاجها من القديم إلى الجديد.بسيطة جدا.

عندما تقوم بإعادة تسمية قاعدة بيانات في PHPMyAdmin، فإنه يقوم بإنشاء ملف تفريغ، ثم يقوم بإسقاط قاعدة البيانات وإعادة إنشائها بالاسم الجديد.

بالنسبة لأولئك الذين هم مستخدمي Mac، يحتوي Sequel Pro على خيار إعادة تسمية قاعدة البيانات في قائمة قاعدة البيانات.http://www.sequelpro.com/

حسنًا هناك طريقتان:

طريقة 1: إحدى الطرق المعروفة لإعادة تسمية مخطط قاعدة البيانات هي تفريغ المخطط باستخدام Mysqldump واستعادته في مخطط آخر، ثم إسقاط المخطط القديم (إذا لزم الأمر).

من شل

 mysqldump emp > emp.out
 mysql -e "CREATE DATABASE employees;"
 mysql employees < emp.out 
 mysql -e "DROP DATABASE emp;"

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

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

الطريقة الثانية: يتمتع MySQL بميزة جيدة جدًا لإعادة تسمية الجداول التي تعمل أيضًا عبر مخططات مختلفة.عملية إعادة التسمية هذه هي عملية ذرية ولا يمكن لأي شخص آخر الوصول إلى الجدول أثناء إعادة تسميته.يستغرق هذا وقتًا قصيرًا حتى يكتمل نظرًا لأن تغيير اسم الجدول أو مخططه هو مجرد تغيير في بيانات التعريف.هنا هو النهج الإجرائي في القيام بإعادة التسمية:

قم بإنشاء مخطط قاعدة البيانات الجديد بالاسم المطلوب.أعد تسمية الجداول من المخطط القديم إلى المخطط الجديد، باستخدام أمر "RENAME TABLE" الخاص بـ MySQL.قم بإسقاط مخطط قاعدة البيانات القديم.If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too.يفشل "إعادة تسمية الجدول" الخاص بـ MySQL في حالة وجود مشغلات على الجداول.ولمعالجة ذلك يمكننا القيام بالأمور التالية:

1) Dump the triggers, events and stored routines in a separate file. يتم ذلك باستخدام إشارات -E و -R (بالإضافة إلى -t -d التي تفريغ المشغلات) إلى أمر mysqldump.بمجرد تفريغ المشغلات، سنحتاج إلى إسقاطها من المخطط، حتى يعمل أمر RENAME TABLE.

 $ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out

2) قم بإنشاء قائمة بالجداول "BASE" فقط.يمكن العثور على هذه باستخدام استعلام على information_schema.TABLES طاولة.

 mysql> select TABLE_NAME from information_schema.tables where 
    table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';

3) تفريغ وجهات النظر في ملف الخروج.يمكن العثور على طرق العرض باستخدام استعلام على نفسه information_schema.TABLES طاولة.

mysql> select TABLE_NAME from information_schema.tables where 
   table_schema='<old_schema_name>' and TABLE_TYPE='VIEW';
 $ mysqldump <database> <view1> <view2> … > views.out

4) قم بإسقاط المشغلات على الجداول الحالية في المخطط القديم.

mysql> DROP TRIGGER <trigger_name>;
...

5) قم باستعادة ملفات التفريغ المذكورة أعلاه بمجرد إعادة تسمية كافة الجداول "الأساسية" الموجودة في الخطوة رقم 2.

mysql> RENAME TABLE <old_schema>.table_name TO <new_schema>.table_name;
...
$ mysql <new_schema> < views.out
$ mysql <new_schema> < stored_routines_triggers_events.out

تعقيدات الأساليب المذكورة أعلاه:قد نحتاج إلى تحديث المنح للمستخدمين بحيث يطابقون اسم المخطط الصحيح.يمكن إصلاح هذه المشاكل بتحديث بسيط على mysql.columns_priv وmysql.procs_priv وmysql.tables_priv وجداول mysql.db بتحديث اسم المخطط القديم إلى مخطط جديد واستدعاء "امتيازات التدفق؛".على الرغم من أن "الطريقة 2" تبدو أكثر تعقيدًا بعض الشيء من "الطريقة 1"، إلا أنها قابلة للبرمجة تمامًا.يمكن أن يساعدك برنامج bash النصي البسيط لتنفيذ الخطوات المذكورة أعلاه بالتسلسل الصحيح في توفير المساحة والوقت أثناء إعادة تسمية مخططات قاعدة البيانات في المرة القادمة.

قام فريق Percona Remote DBA بكتابة برنامج نصي يسمى "rename_db" والذي يعمل بالطريقة التالية:

[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>

لتوضيح استخدام هذا البرنامج النصي، استخدم نموذج مخطط "emp"، وأنشأ مشغلات اختبار، وإجراءات مخزنة على هذا المخطط.ستتم محاولة إعادة تسمية مخطط قاعدة البيانات باستخدام البرنامج النصي، الذي يستغرق بعض الثواني لإكماله على عكس طريقة التفريغ/الاستعادة التي تستغرق وقتًا طويلاً.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp                |
| mysql              |
| performance_schema |
| test               |
+--------------------+


[root@dba ~]# time /tmp/rename_db localhost emp emp_test
create database emp_test DEFAULT CHARACTER SET latin1
drop trigger salary_trigger
rename table emp.__emp_new to emp_test.__emp_new
rename table emp._emp_new to emp_test._emp_new
rename table emp.departments to emp_test.departments
rename table emp.dept to emp_test.dept
rename table emp.dept_emp to emp_test.dept_emp
rename table emp.dept_manager to emp_test.dept_manager
rename table emp.emp to emp_test.emp
rename table emp.employees to emp_test.employees
rename table emp.salaries_temp to emp_test.salaries_temp
rename table emp.titles to emp_test.titles
loading views
loading triggers, routines and events
Dropping database emp

real    0m0.643s
user    0m0.053s
sys     0m0.131s


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| emp_test           |
| mysql              |
| performance_schema |
| test               |
+--------------------+

كما ترون في الإخراج أعلاه تمت إعادة تسمية مخطط قاعدة البيانات "emp" إلى "emp_test" في أقل من ثانية.وأخيرًا، هذا هو البرنامج النصي من Percona المستخدم أعلاه لـ "الطريقة الثانية".

#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
set -e
if [ -z "$3" ]; then
    echo "rename_db <server> <database> <new_database>"
    exit 1
fi
db_exists=`mysql -h $1 -e "show databases like '$3'" -sss`
if [ -n "$db_exists" ]; then
    echo "ERROR: New database already exists $3"
    exit 1
fi
TIMESTAMP=`date +%s`
character_set=`mysql -h $1 -e "show create database $2\G" -sss | grep ^Create | awk -F'CHARACTER SET ' '{print $2}' | awk '{print $1}'`
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
    echo "Error retrieving tables from $2"
    exit 1
fi
echo "create database $3 DEFAULT CHARACTER SET $character_set"
mysql -h $1 -e "create database $3 DEFAULT CHARACTER SET $character_set"
TRIGGERS=`mysql -h $1 $2 -e "show triggers\G" | grep Trigger: | awk '{print $2}'`
VIEWS=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
    mysqldump -h $1 $2 $VIEWS > /tmp/${2}_views${TIMESTAMP}.dump
fi
mysqldump -h $1 $2 -d -t -R -E > /tmp/${2}_triggers${TIMESTAMP}.dump
for TRIGGER in $TRIGGERS; do
    echo "drop trigger $TRIGGER"
    mysql -h $1 $2 -e "drop trigger $TRIGGER"
done
for TABLE in $TABLES; do
    echo "rename table $2.$TABLE to $3.$TABLE"
    mysql -h $1 $2 -e "SET FOREIGN_KEY_CHECKS=0; rename table $2.$TABLE to $3.$TABLE"
done
if [ -n "$VIEWS" ]; then
    echo "loading views"
    mysql -h $1 $3 < /tmp/${2}_views${TIMESTAMP}.dump
fi
echo "loading triggers, routines and events"
mysql -h $1 $3 < /tmp/${2}_triggers${TIMESTAMP}.dump
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
if [ -z "$TABLES" ]; then
    echo "Dropping database $2"
    mysql -h $1 $2 -e "drop database $2"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.columns_priv where db='$2'" -sss` -gt 0 ]; then
    COLUMNS_PRIV="    UPDATE mysql.columns_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.procs_priv where db='$2'" -sss` -gt 0 ]; then
    PROCS_PRIV="    UPDATE mysql.procs_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.tables_priv where db='$2'" -sss` -gt 0 ]; then
    TABLES_PRIV="    UPDATE mysql.tables_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.db where db='$2'" -sss` -gt 0 ]; then
    DB_PRIV="    UPDATE mysql.db set db='$3' WHERE db='$2';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
    echo "IF YOU WANT TO RENAME the GRANTS YOU NEED TO RUN ALL OUTPUT BELOW:"
    if [ -n "$COLUMNS_PRIV" ]; then echo "$COLUMNS_PRIV"; fi
    if [ -n "$PROCS_PRIV" ]; then echo "$PROCS_PRIV"; fi
    if [ -n "$TABLES_PRIV" ]; then echo "$TABLES_PRIV"; fi
    if [ -n "$DB_PRIV" ]; then echo "$DB_PRIV"; fi
    echo "    flush privileges;"
fi

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

DROP PROCEDURE IF EXISTS mysql.rename_db;
DELIMITER ||
CREATE PROCEDURE mysql.rename_db(IN old_db VARCHAR(100), IN new_db VARCHAR(100))
BEGIN
SELECT CONCAT('CREATE DATABASE ', new_db, ';') `# create new database`;
SELECT CONCAT('RENAME TABLE `', old_db, '`.`', table_name, '` TO `', new_db, '`.`', table_name, '`;') `# alter table` FROM information_schema.tables WHERE table_schema = old_db;
SELECT CONCAT('DROP DATABASE `', old_db, '`;') `# drop old database`;
END||
DELIMITER ;

$ time mysql -uroot -e "call mysql.rename_db('db1', 'db2');" | mysql -uroot

ومع ذلك، فإن أي مشغلات في قاعدة البيانات المستهدفة لن تكون سعيدة.ستحتاج إلى إسقاطها أولاً ثم إعادة إنشائها بعد إعادة التسمية.

mysql -uroot -e "call mysql.rename_db('test', 'blah2');" | mysql -uroot
ERROR 1435 (HY000) at line 4: Trigger in wrong schema

معظم الإجابات هنا خاطئة لأحد السببين:

  1. لا يمكنك استخدام RENAME TABLE فقط، لأنه قد تكون هناك طرق عرض ومشغلات.إذا كانت هناك مشغلات، فستفشل إعادة تسمية الجدول
  2. لا يمكنك استخدام mysqldump إذا كنت تريد "بسرعة" (كما هو مطلوب في السؤال) إعادة تسمية قاعدة بيانات كبيرة

لدى بيركونا منشور مدونة حول كيفية القيام بذلك بشكل جيد:https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/

والنص الذي تم نشره (صنعه؟) بواسطة Simon R Jones يقوم بما هو مقترح في هذا المنشور.لقد أصلحت الخلل الذي وجدته في البرنامج النصي.يمكنك أن ترى هنا:

https://Gist.github.com/ryantm/76944318b0473ff25993ef2a7186213d

وهنا نسخة منه:

#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
# @see https://www.percona.com/blog/2013/12/24/renaming-database-schema-mysql/
set -e
if [ -z "$3" ]; then
    echo "rename_db <server> <database> <new_database>"
    exit 1
fi
db_exists=`mysql -h $1 -e "show databases like '$3'" -sss`
if [ -n "$db_exists" ]; then
    echo "ERROR: New database already exists $3"
    exit 1
fi
TIMESTAMP=`date +%s`
character_set=`mysql -h $1 -e "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '$2'" -sss`
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
    echo "Error retrieving tables from $2"
    exit 1
fi
echo "create database $3 DEFAULT CHARACTER SET $character_set"
mysql -h $1 -e "create database $3 DEFAULT CHARACTER SET $character_set"
TRIGGERS=`mysql -h $1 $2 -e "show triggers\G" | grep Trigger: | awk '{print $2}'`
VIEWS=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
    mysqldump -h $1 $2 $VIEWS > /tmp/${2}_views${TIMESTAMP}.dump
fi
mysqldump -h $1 $2 -d -t -R -E > /tmp/${2}_triggers${TIMESTAMP}.dump
for TRIGGER in $TRIGGERS; do
    echo "drop trigger $TRIGGER"
    mysql -h $1 $2 -e "drop trigger $TRIGGER"
done
for TABLE in $TABLES; do
    echo "rename table $2.$TABLE to $3.$TABLE"
    mysql -h $1 $2 -e "SET FOREIGN_KEY_CHECKS=0; rename table $2.$TABLE to $3.$TABLE"
done
if [ -n "$VIEWS" ]; then
    echo "loading views"
    mysql -h $1 $3 < /tmp/${2}_views${TIMESTAMP}.dump
fi
echo "loading triggers, routines and events"
mysql -h $1 $3 < /tmp/${2}_triggers${TIMESTAMP}.dump
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
if [ -z "$TABLES" ]; then
    echo "Dropping database $2"
    mysql -h $1 $2 -e "drop database $2"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.columns_priv where db='$2'" -sss` -gt 0 ]; then
    COLUMNS_PRIV="    UPDATE mysql.columns_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.procs_priv where db='$2'" -sss` -gt 0 ]; then
    PROCS_PRIV="    UPDATE mysql.procs_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.tables_priv where db='$2'" -sss` -gt 0 ]; then
    TABLES_PRIV="    UPDATE mysql.tables_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.db where db='$2'" -sss` -gt 0 ]; then
    DB_PRIV="    UPDATE mysql.db set db='$3' WHERE db='$2';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
    echo "IF YOU WANT TO RENAME the GRANTS YOU NEED TO RUN ALL OUTPUT BELOW:"
    if [ -n "$COLUMNS_PRIV" ]; then echo "$COLUMNS_PRIV"; fi
    if [ -n "$PROCS_PRIV" ]; then echo "$PROCS_PRIV"; fi
    if [ -n "$TABLES_PRIV" ]; then echo "$TABLES_PRIV"; fi
    if [ -n "$DB_PRIV" ]; then echo "$DB_PRIV"; fi
    echo "    flush privileges;"
fi

احفظه في ملف يسمى rename_db وجعل البرنامج النصي قابلاً للتنفيذ باستخدام chmod +x rename_db ثم استخدمه مثل ./rename_db localhost old_db new_db

إليك ملف دفعي كتبته لتشغيله تلقائيًا من سطر الأوامر، ولكنه مخصص لنظام التشغيل Windows/MS-DOS.

بناء الجملة هو قاعدة بيانات rename_mysqldb newdatabase -u [user] -p[password]

:: ***************************************************************************
:: FILE: RENAME_MYSQLDB.BAT
:: ***************************************************************************
:: DESCRIPTION
:: This is a Windows /MS-DOS batch file that automates renaming a MySQL database 
:: by using MySQLDump, MySQLAdmin, and MySQL to perform the required tasks.
:: The MySQL\bin folder needs to be in your environment path or the working directory.
::
:: WARNING: The script will delete the original database, but only if it successfully
:: created the new copy. However, read the disclaimer below before using.
::
:: DISCLAIMER
:: This script is provided without any express or implied warranties whatsoever.
:: The user must assume the risk of using the script.
::
:: You are free to use, modify, and distribute this script without exception.
:: ***************************************************************************

:INITIALIZE
@ECHO OFF
IF [%2]==[] GOTO HELP
IF [%3]==[] (SET RDB_ARGS=--user=root) ELSE (SET RDB_ARGS=%3 %4 %5 %6 %7 %8 %9)
SET RDB_OLDDB=%1
SET RDB_NEWDB=%2
SET RDB_DUMPFILE=%RDB_OLDDB%_dump.sql
GOTO START

:START
SET RDB_STEP=1
ECHO Dumping "%RDB_OLDDB%"...
mysqldump %RDB_ARGS% %RDB_OLDDB% > %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=2
ECHO Creating database "%RDB_NEWDB%"...
mysqladmin %RDB_ARGS% create %RDB_NEWDB%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=3
ECHO Loading dump into "%RDB_NEWDB%"...
mysql %RDB_ARGS% %RDB_NEWDB% < %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=4
ECHO Dropping database "%RDB_OLDDB%"...
mysqladmin %RDB_ARGS% drop %RDB_OLDDB% --force
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
SET RDB_STEP=5
ECHO Deleting dump...
DEL %RDB_DUMPFILE%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR_ABORT
ECHO Renamed database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:ERROR_ABORT
IF %RDB_STEP% GEQ 3 mysqladmin %RDB_ARGS% drop %NEWDB% --force
IF %RDB_STEP% GEQ 1 IF EXIST %RDB_DUMPFILE% DEL %RDB_DUMPFILE%
ECHO Unable to rename database "%RDB_OLDDB%" to "%RDB_NEWDB%".
GOTO END

:HELP
ECHO Renames a MySQL database.
ECHO Usage: %0 database new_database [OPTIONS]
ECHO Options: Any valid options shared by MySQL, MySQLAdmin and MySQLDump.
ECHO          --user=root is used if no options are specified.
GOTO END    

:END
SET RDB_OLDDB=
SET RDB_NEWDB=
SET RDB_ARGS=
SET RDB_DUMP=
SET RDB_STEP=

الإجراء المخزن في TodoInTX لم ينجح تمامًا بالنسبة لي.وهنا طعنتي في ذلك:

-- stored procedure rename_db: Rename a database my means of table copying.
-- Caveats: 
-- Will clobber any existing database with the same name as the 'new' database name.
-- ONLY copies tables; stored procedures and other database objects are not copied.
-- Tomer Altman (taltman@ai.sri.com)

delimiter //
DROP PROCEDURE IF EXISTS rename_db;
CREATE PROCEDURE rename_db(IN old_db VARCHAR(100), IN new_db VARCHAR(100))
BEGIN
    DECLARE current_table VARCHAR(100);
    DECLARE done INT DEFAULT 0;
    DECLARE old_tables CURSOR FOR select table_name from information_schema.tables where table_schema = old_db;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    SET @output = CONCAT('DROP SCHEMA IF EXISTS ', new_db, ';'); 
    PREPARE stmt FROM @output;
    EXECUTE stmt;

    SET @output = CONCAT('CREATE SCHEMA IF NOT EXISTS ', new_db, ';');
    PREPARE stmt FROM @output;
    EXECUTE stmt;

    OPEN old_tables;
    REPEAT
        FETCH old_tables INTO current_table;
        IF NOT done THEN
        SET @output = CONCAT('alter table ', old_db, '.', current_table, ' rename ', new_db, '.', current_table, ';');
        PREPARE stmt FROM @output;
        EXECUTE stmt;

        END IF;
    UNTIL done END REPEAT;

    CLOSE old_tables;

END//
delimiter ;

الخطوات :

  1. يضرب http://localhost/phpmyadmin/
  2. حدد قاعدة البيانات الخاصة بك
  3. انقر فوق علامة التبويب العمليات
  4. ستكون هناك علامة تبويب باسم "إعادة تسمية قاعدة البيانات إلى".أضف اسمًا جديدًا وتحقق من ضبط الامتيازات.
  5. انقر على اذهب.

enter image description here

أنا طرح سؤال على خطأ الخادم محاولة التغلب على وقت التوقف عن العمل عند استعادة قواعد بيانات كبيرة جدًا باستخدام MySQL Proxy.لم أحقق أي نجاح، لكنني أدركت في النهاية أن ما أردته هو وظيفة إعادة تسمية قاعدة البيانات لأن التفريغ/الاستيراد لم يكن خيارًا نظرًا لحجم قاعدة البيانات الخاصة بنا.

هناك وظيفة RENAME TABLE مضمنة في MySQL، لذلك انتهى بي الأمر بكتابة برنامج Python بسيط للقيام بهذه المهمة نيابةً عني.لدي نشره على جيثب في حال كان من الممكن أن يكون مفيدًا للآخرين.

من أجل راحتك، يوجد أدناه نص برمجي صغير يجب تنفيذه باستخدام معلمتين:اسم db واسم db الجديد.

قد تحتاج إلى إضافة معلمات تسجيل الدخول إلى خطوط mysql إذا كنت لا تستخدم ملف .my.cnf في الدليل الرئيسي الخاص بك.الرجاء عمل نسخة احتياطية قبل تنفيذ هذا البرنامج النصي.


#!/usr/bin/env bash

mysql -e "CREATE DATABASE $2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
for i in $(mysql -Ns $1 -e "show tables");do
    echo "$1.$i -> $2.$i"
    mysql -e "rename TABLE $1.$i to $2.$i"
done
mysql -e "DROP DATABASE $1"

إن أبسط طريقة هي استخدام برنامج HeidiSQL.إنه مجاني ومفتوح المصدر.يعمل على نظام التشغيل Windows وعلى أي نظام Linux مزود بـ خمر (تشغيل تطبيقات Windows على Linux وBSD وSolaris وMac OS X).

لتنزيل HeidiSQL، انتقل إلى http://www.heidisql.com/download.php.

لتنزيل النبيذ، انتقل إلى http://www.winehq.org/.

لإعادة تسمية قاعدة بيانات في HeidiSQL، ما عليك سوى النقر بزر الماوس الأيمن على اسم قاعدة البيانات وتحديد "تحرير".ثم أدخل اسمًا جديدًا واضغط على "موافق".

انها بسيطة جدا.

فيما يلي طريقة سريعة لإنشاء برنامج نصي لإعادة تسمية SQL، إذا كان لديك العديد من الجداول لنقلها.

SELECT DISTINCT CONCAT('RENAME TABLE ', t.table_schema,'.', t.table_name, ' TO ',     
t.table_schema, "_archive", '.', t.table_name, ';' ) as Rename_SQL 
FROM information_schema.tables t
WHERE table_schema='your_db_name' ;

يبدو أن أحداً لم يذكر هذا ولكن إليك طريقة أخرى:

create database NewDatabaseName like OldDatabaseName;

ثم لكل جدول قم بما يلي:

create NewDatabaseName.tablename like OldDatabaseName.tablename;
insert into NewDataBaseName.tablename select * from OldDatabaseName.tablename;

ثم، إذا كنت تريد،

drop database OldDatabaseName;

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

إذا كان لديك إجراءات/طرق عرض مخزنة/وما إلى ذلك، فقد ترغب في نقلها أيضًا.

لمستخدمي ماك، يمكنك استخدام Sequel Pro (مجاني)، والذي يوفر فقط خيار إعادة تسمية قواعد البيانات.على الرغم من أنه لا يحذف قاعدة البيانات القديمة.

بمجرد فتح قاعدة البيانات ذات الصلة، انقر فقط على: Database --> Rename database...

في MySQL Administrator قم بما يلي:

  1. ضمن الكتالوجات، قم بإنشاء مخطط قاعدة بيانات جديد.
  2. انتقل إلى النسخ الاحتياطي وإنشاء نسخة احتياطية للمخطط القديم.
  3. تنفيذ النسخ الاحتياطي.
  4. انتقل إلى استعادة وفتح الملف الذي تم إنشاؤه في الخطوة 3.
  5. حدد "مخطط آخر" ضمن مخطط الهدف وحدد مخطط قاعدة البيانات الجديد.
  6. ابدأ الاستعادة.
  7. تحقق من المخطط الجديد ، وإذا كان يبدو جيدًا ، فقم بحذف المخطط القديم.

في phpmyadmin يمكنك بسهولة إعادة تسمية قاعدة البيانات

select database 

  goto operations tab

  in that rename Database to :

  type your new database name and click go

اطلب إسقاط الجدول القديم وإعادة تحميل بيانات الجدول، ثم انقر فوق "موافق" في كليهما

تتم إعادة تسمية قاعدة البيانات الخاصة بك

إذا كنت تستخدم phpMyAdmin يمكنك الانتقال إلى علامة التبويب "العمليات" بمجرد تحديد قاعدة البيانات التي تريد إعادة تسميتها.ثم انتقل إلى القسم الأخير "نسخ قاعدة البيانات إلى" (أو شيء من هذا القبيل)، وقم بإدراج اسم، وحدد الخيارات أدناه.في هذه الحالة، أعتقد أنه يجب عليك تحديد مربعي الاختيار "البنية والبيانات" و"إنشاء قاعدة البيانات قبل النسخ"، وأخيرًا، الضغط على الزر "انتقال" في هذا القسم.

بالمناسبة، أنا أستخدم phpMyAdmin باللغة الإسبانية لذا لست متأكدًا من أسماء الأقسام باللغة الإنجليزية.

فيما يلي مقتطف Bash من سطر واحد لنقل جميع الجداول من مخطط إلى آخر:

history -d $((HISTCMD-1)) && mysql -udb_user -p'db_password' -Dold_schema -ABNnqre'SHOW TABLES;' | sed -e's/.*/RENAME TABLE old_schema.`&` TO new_schema.`&`;/' | mysql -udb_user -p'db_password' -Dnew_schema

يضمن أمر السجل في البداية عدم حفظ أوامر MySQL التي تحتوي على كلمات مرور في سجل الصدفة.

تأكد من أن db_user لديه أذونات القراءة/الكتابة/الإفلات في المخطط القديم، وأذونات القراءة/الكتابة/الإنشاء في المخطط الجديد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top