简体   繁体   中英

Cannot drop index '***': needed in a foreign key constraint

I have created unique index:

 $table->unique(['owner_id', 'promoter_id']);

and now i tray drop it

$table->dropUnique(['owner_id', 'promoter_id']);

General error: 1553 Cannot drop index 'connections_owner_id_promoter_id_unique': needed in a foreign key constraint (SQL: alter table connections drop index connections_owner_id_promoter_id_unique)

Also, i tried to drop foreign key before

$table->dropForeign('connections_promoter_id_foreign');

but still no results

From Laravel docs on Indexes , you can create the unique index with an assigned name:

在此处输入图像描述

So just to save you of debugging how laravel constructs the name to the index, you may assign it a name when adding the index eg:

$table->unique(['owner_id', 'promoter_id'], 'owner_promoter_index');

Then when you drop it, you use the same name:

$table->dropUnique('owner_promoter_index');

Based on this Drop muli-column unique key without dropping foreign key? i got this solution which also works:

Schema::table('connections', function ($table){
            $table->index('owner_id');
            $table->dropUnique(['owner_id', 'promoter_id']);
        });

in your example

$table->unique(['owner_id', 'promoter_id']);

the first column in the array already has a foreign key and a related index.

The First option would be to put first a field that does not have a foreign key already, like

$table->unique(["key", 'owner_id', 'promoter_id']);

But it is not always possible

The second option - you just need to modify the down() function

For example you create your unique index like this

$table->unique(['owner_id', 'promoter_id']);

owner_id is the field that gives you troubles now because it goes the first in the array. Thus, the down function should look like this:

$table->dropForeign(['owner_id']);
$table->dropUnique(['owner_id', 'promoter_id']);
$table->foreign('owner_id')->references('id')->on('owners');

The third option is a bit trickier, your 'down' function will look like this

$table->index('owner_id');
$table->dropUnique(['owner_id', 'promoter_id']);

It will work, but I don't recommend it , because it is not quite a `rollback'

If you start with index name records_owner_id_foreign then you do php artisan migrate and then php artisan migrate:rollback and then you will find your index name records_owner_id_index . It is not the same index name any more

So potentially you can have different index names in different databases, do you like it? I don't.

Try this way:

   Schema::table('table_name', function (Blueprint $table) {
        
        
        //$table->dropIndex('language_title');            
        //$table->dropUnique('language_title');

        // Integrate them
        $table->dropIndex('language_title')->dropUnique('language_title');
    });

From the error message, it seems that you created a foreign key and the unique touple in the same run, like this:

$table->foreignId('owner_id')->constrained('owners');
$table->unique(['owner_id', 'promoter_id']);

From mysql docs :

MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created.

Now as you created a tuple index, owner_id already has an index and there is no need for MySQL to create a foreign_key index. However, if you would remove the unique key constrain now, you would have a foreignkey without index. This is not allowed, and therefore your error message.

There is no need to remove the foreign key. Just add a normal index on the field before you remove the unique index. Like this:

$table->index('owner_id');
$table->dropUnique(['owner_id', 'promoter_id']);

That's it. The foreign key error won't appear, as you have it indexed.

NO NEED to disable or delete unique index! Just override the UNIQUE index with another one!

Schema::table('users', function (Blueprint $table) {
    $table->unique(['user_id', 'role_id', 'department_id'],
       'user_roles_user_id_role_id_department_id_unique');
});

使用PHP管理员,我有同样的问题,但很容易从那里做到!

Drop the constraint first.

for sqlserver: if you don't know the constraint name,use sp_helpconstraint TABLE_A ,the constraint name maybe the same as index. then alter table TABLE_A drop constraint UQ__TABLE_A_XXXXXXXXXX .Then,drop the index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM