У нас было много опыта чистки базы данных WooCommerce в WordPress для ускорения сайтов.
Если вы видите эту ошибку в phpMyAdmin «Current selection does not contain a unique column», то этот пост для вас!
Сначала проверьте структуру таблицы wp_options с этой командой, мы используем wp-cli, но вы можете использовать Adminer или PhpMyAdmin
wp db query "DESCRIBE wp_options"
Этот вывод показывает нам, что нет первичного ключа ( option_id
) и нет уникального ограничения накладываемое на колонку option_name
+--------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+-------+ | option_id | bigint(20) unsigned | NO | | NULL | | | option_name | varchar(191) | YES | | NULL | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+-------+
Это то, как правильная таблица wp_options
выглядит с первичным ключом и ограничением уникальности
+--------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+----------------+ | option_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | YES | UNI | | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+----------------+
Для того, чтобы сделать столбец option_id первичным ключом, вы можете запустить этот запрос
wp db query "ALTER TABLE wp_options MODIFY option_id INT AUTO_INCREMENT PRIMARY KEY;"
Теперь проверьте, как он работал
wp db query "DESCRIBE wp_options"
Похоже, первичный ключ теперь включен, время для уникального ограничения на колонке option_name
+--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | option_id | int(11) | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | YES | | NULL | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+--------------+------+-----+---------+----------------+
Этот запрос будет пытаться добавить ограничение уникальности на колонку option_name
wp db query "ALTER TABLE wp_options ADD UNIQUE (option_name);"
Если вы получите сообщение об ошибке, такую как ERROR 1062 (23000) at line 1: Duplicate entry 'jetpack_available_modules' for key 'option_name'
то есть некоторые повторяющиеся значения option_name
, вы можете просматривать их с этим запросом
wp db query "SELECT option_name, COUNT(*) optioncount FROM wp_options GROUP BY option_name HAVING optioncount > 1 ORDER BY optioncount DESC;"
В порядке возрастания здесь все дубликаты, которые мы собираемся удалить их автоматически
+---------------------------------------------+-------------+ | option_name | optioncount | +---------------------------------------------+-------------+ | jpsq_sync_checkout | 19 | | widget_wpex_users_grid | 5 | | optin_monster | 2 | | wpmandrill-stats | 2 | | widget_wpex_social_widget | 2 | | widget_pages | 2 | | widget_wpex_flickr | 2 | | widget_shapely_recent_posts | 2 | | widget_tag_cloud | 2 | | widget_wpex_recent_posts_thumb_grid | 2 | | widget_shapely-cats | 2 | | widget_akismet_widget | 2 | | widget_shapely_home_parallax | 2 | | rewrite_rules | 2 | | widget_shapely_home_features | 2 | | wpb_js_templates | 2 | | widget_shapely_home_cfa | 2 | | widget_bbp_forums_widget | 2 | | _transient_doing_cron | 2 | | widget_bbp_login_widget | 2 | | widget_shapely_home_clients | 2 | | yst_ga_top_pageviews | 2 | | widget_media_image | 2 | | widget_shapely_video_widget | 2 | | widget_media_video | 2 | | widget_text | 2 | | widget_rss | 2 | | wpseo_onpage | 2 | | image-lazy-load | 2 | +---------------------------------------------+-------------+
Автоматическое удаление повторяющихся значений в таблице OPTION_NAME можно сделать двумя способами: с использованием старого значения option_id (наименьшее число) или новейшее значение option_id (самый большой номер).
Это сохраняет старое (минимальное) option_id
для любых повторяющихся значений option_name
DELETE FROM wp_2_options WHERE option_id NOT IN (SELECT * FROM (SELECT MIN(n.option_id) FROM wp_2_options n GROUP BY n.option_name) x)
Вот один запрос для использования команды wp-cli для запроса базы данных
wp db query "DELETE FROM wp_options WHERE option_id NOT IN (SELECT * FROM (SELECT MIN(n.option_id) FROM wp_options n GROUP BY n.option_name) x)"
Он содержит новое (максимальное) option_id
для любых повторяющихся значений option_name
DELETE FROM wp_options WHERE option_id NOT IN (SELECT * FROM (SELECT MAX(n.option_id) FROM wp_options n GROUP BY n.option_name) x)
Вот одна строка для использования с командой wp-cli для запроса базы данных
wp db query "DELETE FROM wp_options WHERE option_id NOT IN (SELECT * FROM (SELECT MAX(n.option_id) FROM wp_options n GROUP BY n.option_name) x)"
Теперь давайте сделаем уникальное ограничение снова на колонке option_name
wp db query "ALTER TABLE wp_options ADD UNIQUE (option_name);"
Если вы не получили каких-либо ошибок, то проверьте таблицу снова
wp db query "DESCRIBE wp_options;"
Результат должен быть такой:
+--------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+----------------+ | option_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | NO | UNI | | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+----------------+