Сделав в wordpress мультисайтинг, я добавил в сеть ещё один сайт, а через некоторое время добавил английскую версию для блога, который в списке сайтов стоял первым. Английская версия встала, разумеется, в конец, а мне хотелось, чтобы она стояла под своей русской версией. Есть много способов сделать это, например, создав greasemonkey-скрипт, или написав плагин для wordpress, и, пожалуй, самым неразумным будет изменение данных в mysql-базе, но именно так я и поступил =)
Итак, есть блог с идентификатором 1, потом ещё один блог с id 2, и английская версия первого блога с id 3. Английская версия должна стать блогом с id 2, а блог с текущим id 2 должен стать с id 3. Пока есть блог с id 2, я не могу сразу блог с id 3 делать блогом с id 2, поэтому 2 сначала будет становиться 4, потом 3 будет становиться 2, и в конце уже 4 будет становиться 3.
Список блогов находится в таблице wp_blogs, начнём с неё:
UPDATE wp_blogs SET blog_id=4 WHERE blog_id=2; UPDATE wp_blogs SET blog_id=2 WHERE blog_id=3; UPDATE wp_blogs SET blog_id=3 WHERE blog_id=4;
Но осталась ещё куча данных, завязанных на старые id, их нужно искать и менять. Начнём с таблиц.
При создании каждого блога, в mysql-базе создаются таблицы commentmeta, comments, links, options, postmeta, posts, term_relationships, term_taxonomy, terms с префиксом «wp_n_», где n – идентификатор блога в таблице wp_blogs (кроме блога с id 1). Если непонятно написал – создаются таблицы вида wp_2_commentmeta и т.д.
Переименовывать будем командой RENAME TABLE. Но для каждого блога 9 таблиц, и нам нужно сначала 2 перевести в 4, а только потом 3 в 2 и 4 в 3, поэтому выйдет 27 команд. Писать от руки – долго, поэтому пусть команды сгенерируются сами.
Select Concat( 'RENAME TABLE ', table_name, ' TO ', REPLACE(table_name, 'wp_2_', 'wp_4_'), ';' ) From information_schema.tables Where table_schema = 'имя_базы' AND table_name LIKE 'wp_2_%';
Осталось только их скопировать и выполнить. Далее то же самое нужно сделать, для wp_3_ -> wp_2_ и wp_4_ -> wp_3_ (заменять не только в REPLACE, но и в LIKE).
По поводу LIKE: условие сейчас не совсем корректное. В LIKE нижнее подчёркивание «_» это один любой символ. То есть условие подходит и для «wpp2w», «wpa2z» и прочих подобных. Но так как мы знаем, что у нас в базе ничего подобного нет, в данном случае можно пренебречь. Корректное условие такое: AND table_name LIKE ‘wp!_2!_%’ escape ‘!’;
Не понравилось, что в таблице wp_n_options роли пользователя сохранены под именем wp_n_user_roles. Зачем эта привязка, нельзя было просто user_roles? Впрочем, меняем:
UPDATE wp_2_options SET option_name='wp_2_user_roles' WHERE option_name='wp_3_user_roles'; UPDATE wp_3_options SET option_name='wp_3_user_roles' WHERE option_name='wp_2_user_roles';
Осталось ещё изменить данные в wp_usermeta:
UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_2_','wp_4_') WHERE meta_key LIKE 'wp_2_%'; UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_3_','wp_2_') WHERE meta_key LIKE 'wp_3_%'; UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_4_','wp_3_') WHERE meta_key LIKE 'wp_4_%';
Теперь всё связано как надо. Если путь сохранения файлов был типа «wp-content/blogs.dir/2/files», то можно и его заменить на соответствующий.