Масове видалення (drop) таблиць бд mysql по префіксу, direqtor

При роботі з різними CMS часто зустрічається завдання видалити в БД MySQL відразу велику кількість таблиць з одним префіксом. Особливо в тому випадку, коли одна БД використовується декількома системами зі своїми префіксами.

Залишу тут для себе і відвідувачів кілька варіантів

Цей спосіб знаходиться на різних ресурсах в мережі. Треба виконати запит, підставивши свій prefix. який поверне текст уже нового запиту на видалення таблиць:

SELECT GROUP_CONCAT # 40; 'DROP TABLE'. table_name. ';' SEPARATOR '' # 41; AS statement
FROM information_schema. tables
WHERE table_name LIKE 'prefix \ _%';

Висновок обов'язково перевірте очима. GROUP_CONCAT обрізає його по довжині змінної group_concat_max_len (замовчування - 1024). Тому вже з 20-25 таблицями ви отримаєте помилкові запити.

Врахувати це можна ось таким чином:

SET SESSION group_concat_max_len = 1000000;
SELECT GROUP_CONCAT # 40; 'DROP TABLE'. table_name. ';' SEPARATOR '' # 41; AS statement
FROM information_schema. tables
WHERE table_name LIKE 'prefix \ _%';

Отриманий висновок - це запит на видалення шуканих таблиць, який треба виконати будь-яким способом в MySQL. Найзручніше цей спосіб для використовують веб-інтерфейс (наприклад phpMyAdmin) або віконні клієнти (наприклад, MySQL Workbench).

Проте, щоб запрограмувати телефон запитувати довше max_allowed_packet (замовчування 4Gb) отримати і запустити не вийде. Але, думаю, чотирьох гігабайт вистачить кожному. )

Просто підрихтував вихідний варіант на свій смак.

SELECT CONCAT # 40; 'DROP TABLE IF EXISTS `'. GROUP_CONCAT # 40; table_name. ' `,`' SEPARATOR '' # 41 ;. ' `;' # 41; AS statement
FROM information_schema. tables
WHERE table_name LIKE 'prefix \ _%';


Переваги цієї версії зрозумілі:

  • сервер отримує один запит, а не насильство пачкою з сотні DROP-ів, тому відпрацює швидше;
  • код рази в два коротше, відповідно, в обмеження 1024 символів вміститься рази в два більше таблиць;
  • код не викине помилки коли довжина рядка перевищить group_concat_max_len;
  • якщо обмеження перевищені то після виконання першого запиту, можна просто згенерувати новий запит, оскільки разом в нього таблиці вже будуть видалені, їх місце займуть залишилися;
  • імена таблиць захищені лапками `` на випадок збігу імен таблиць з ключовими словами SQL;

Спосіб також підходить для використовують веб-інтерфейс (наприклад, phpMyAdmin) або віконні клієнти (наприклад, MySQL Workbench).

Варіант для BASH

Тут ніяких обмежень немає. В командний рядок (CLI) інтерпретатора bash виводиться простий список таблиць. Запит DROP TABLE формується командами оболонки і знову виконується клієнтської утилітою mysql.

echo "show tables like 'PREFIX \ _%'" | \ # Складаємо запит для отримання списку таблиць. Замініть PREFIX \ _ на необхідний вам.
mysql -N -u USER -pPASS DATABASE | \ # Відправляємо запит в MySQL. Опція -N обрізає висновок заголовка стовпчика.
sed '/^.\+$/!d' | \ # Видаляємо порожні рядки про всяк випадок.
sed 's /.\+/ `` /' | \ # Укладаємо імена таблиць в захисні лапки ``.
sed ': a; N; $! ba; s / \ n /, / g' | \ # Це sed-ово колдунство склеює все рядки в одну через кому.
sed 's /^.\+/ DROP TABLE IF EXISTS ; / '| \ # Дописувати SQL-запит.
mysql -u USER -pPASS DATABASE # Відправляємо запит в MySQL на виконання.
# У 3-й і 7-й рядках вкажіть свої параметри підключення до БД.
# USER - ім'я користувача в MySQL.
# PASS - пароль користувача (між -p і PASS пробіл не потрібен). Можна залишити просто порожню опцію -p і ввести пароль двічі.
# DATABASE - ім'я бази даних, з якою ви працюєте.


Команда bash на видалення таблиць одним рядком.

echo "show tables like 'PREFIX \ _%'" | mysql -N -u USER -pPASS DATABASE | sed '/^.\+$/!d' | sed 's /.\+/ `` /' | sed ': a; N; $! ba; s / \ n /, / g' | sed 's /^.\+/ DROP TABLE IF EXISTS ; / '| mysql -u USER -pPASS DATABASE

Примітка. Символ _ (підкреслення) в операторі LIKE є спеціальним і означає один будь-який символ, тому екранується \ (зворотний слеш). У деяких оболонках Linux зворотний слеш теж може інтерпретуватися спеціальним чином і потребують другого \ перед ним. Враховуйте це і перевіряйте, що передає echo в mysql.