#mysql
#mysql
Вопрос:
У меня есть две большие базы данных MySQL с идентичными схемами, которые я хочу объединить. Для этого я хочу увеличить каждый внешний ключ (и идентификатор, естественно) одной базы данных на 10 миллионов, а затем вставить все записи измененной базы данных в другую базу данных.
Я думал о редактировании mysqldump с помощью таких инструментов, как grep
и gawk
, но это кажется очень сложным для выполнения. Какой подход был бы наилучшим?
Комментарии:
1. Я бы сделал дамп mysql с исходными данными, а затем изменил значения в новой базе данных
2. Если поля FK / PK имеют каскадные обновления, это должно быть несложно сделать
update table set pk_field=pk_field 10000000
. Каскад позаботится о внешних ключах. Затем просто выгрузите эту базу данных в файл и загрузите в другую базу данных.3. База данных содержит 206 таблиц со многими-многими ссылками на FK. Вручную
set
изменять поля не вариант.4. @Mark, Отлично. Но как мне обрабатывать таблицы с самоссылающимися FKS?
Ответ №1:
Выгрузите две базы данных на один сервер. Один из них будет целевой схемой.
- дамп базы данных 1 в final_scheme
- дамп базы данных 2 в aux_scheme
Сделайте это для каждой таблицы (я надеюсь, это не составит труда):
insert into final_scheme.tableA
select id 1000000, name, etc, fk_id 1000000 from aux_scheme.tableA
Я сделал это для частичного слияния (то есть, только некоторых таблиц) и все работало нормально.
Ответ №2:
UPDATE TABLE mytable_foreign SET ID = ID 10000000;
UPDATE TABLE mytable SET FOREIGN_ID = FOREIGN_ID 10000000;
В старой базе данных:
- Снимите ограничения на идентификаторы и внешние идентификаторы
- Обновите данные (используя запрос выше)
- Создавайте резервную копию данных только в виде инструкций INSERT
В новой базе данных:
- Вставьте файл резервной копии
Комментарии:
1. если он собирается объединить один ключ с другим, я бы снял ограничения. Вы не хотите накладных расходов на обслуживание индекса и т.д. При обновлении миллионов строк. Он собирается экспортировать данные и импортировать в первую базу данных, где будут действовать соответствующие ограничения.
2. mysqldump —выбрать базу данных> backup-file.sql ( dev.mysql.com/doc/refman/5.0/fr/mysqldump.html )?
3. это также будет включать инструкции CREATE TABLE, верно? Как мне избежать этого? Спасибо.
4. Прочитайте документы, проведите некоторое исследование. Прежде чем ответить на ваш вопрос, я не знал, но мне потребовалась 1 минута, чтобы найти его … dev.mysql.com/doc/refman/5.1/en /…
Ответ №3:
Хорошо, итак, вот решение, которое я реализовал, используя information_schema
и скрипт bash. Сначала я получаю каждый ключевой столбец в базе данных и таблицу, в которой он встречается, а затем я обновляю каждый из этих столбцов.
echo Incrementing every primary and foreign key by $increment
# Get the table name and column name for every key from the information_schema
select_constraints_sql="select TABLE_NAME, COLUMN_NAME from KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA = 'MyDB'"
# Place the query results in an array
data=( $(mysql -e "$select_constraints_sql" -sN --user=$username --password=$passwd information_schema) )
# Step through the tables and keys and update each, with foreign key checks disabled
# Foreign key checks must be disabled at each step
ignore_fks_sql="SET FOREIGN_KEY_CHECKS = 0"
cnt=${#data[@]}
for (( i=0 ; i < cnt ; i=i 2 ))
do
update_key_sql="$ignore_fks_sql; UPDATE ${data[$i]} SET ${data[$i 1]} = ${data[$i 1]} $increment"
mysql -v -e "$update_key_sql" --user=$username --password=$passwd MyDB
done
# This is just me being a bit pedantic
check_fks_sql="SET FOREIGN_KEY_CHECKS = 1"
mysql -v --user=$username --password=$passwd -e "$check_fks_sql" MyDB