Laravel Миграции: Как добавить индекс, если он, возможно, существует
Вы могли заметить, что нет встроенного способа проверки существование индекса.
Это проблема, потому что, если вы попытаетесь добавить существующий индекс, вы получите сообщение об ошибке duplicate key name
при миграции:
Решение этой проблемы использование простого скрипта загружающего все индексы из базы данных.
Установка Doctrine DBAL
Так как здесь используется Doctrine, нужно будет установить пакет doctrine/dbal
:
composer require doctrine/dbal
В противном случае вы столкнётесь с ошибкой:
Class "Doctrine\DBAL\Driver\AbstractMySQLDriver" not found
Фрагмент кода
Миграция:
Schema::table('TABLE_NAME', static function (Blueprint $table) {
$schemaManager = Schema::getConnection()->getDoctrineSchemaManager();
$indexesFound = $schemaManager->listTableIndexes('TABLE_NAME');
if (! array_key_exists('INDEX_TO_CREATE', $indexesFound)) {
$table->index('FIELD_TO_INDEX', 'INDEX_TO_CREATE');
}
});
Пример 1: Добавление индекса
Например, если вы хотите создать индекс для поля электронной почты в таблице пользователей, вы должны использовать следующий код:
Миграция:
Schema::table('users', static function (Blueprint $table) {
$schemaManager = Schema::getConnection()->getDoctrineSchemaManager();
$indexesFound = $schemaManager->listTableIndexes('users');
if (! array_key_exists('users_email_index', $indexesFound)) {
$table->index('email', 'users_email_index');
}
});
Пример 2: Удаление индекса
И если вы хотите удалить тот же индекс электронной почты, вы должны использовать следующий код:
Миграция:
Schema::table('users', static function (Blueprint $table) {
$schemaManager = Schema::getConnection()->getDoctrineSchemaManager();
$indexesFound = $schemaManager->listTableIndexes('users');
if (array_key_exists('users_email_index', $indexesFound)) {
$table->dropIndex('users_email_index');
}
});
Вот и всё, теперь у вас есть список доступных вам индексов, и вы можете проверить, существует ли индекс, прежде чем пытаться его добавить.