Как удалить ограничение уникальности из таблицы mysql в столбце внешнего ключа

#mysql #database #mariadb #alter-table

#mysql #База данных #mariadb #alter-table

Вопрос:

Я хочу удалить только UNIQUE Constraint из столбца моей таблицы MySQL и сохранить Foreign Key Constraint в столбце как есть. work_id это внешний ключ. Изначально предполагалось, что столбец будет уникальным (отношение «один к одному»), которое теперь не требуется. Я использую MySQL версии 15.1, дистрибутив 5.5.64-MariaDB.

 DESCRIBE requests;
 --------------------- --------------------------------------- ------ ----- --------- ------- 
| Field               | Type                                  | Null | Key | Default | Extra |
 --------------------- --------------------------------------- ------ ----- --------- ------- 
| request_id          | char(32)                              | NO   | PRI | NULL    |       |
| owner               | varchar(100)                          | NO   |     | NULL    |       |
| status              | enum('PENDING','ACCEPTED','REJECTED') | YES  |     | NULL    |       |
| work_id             | char(32)                              | NO   | UNI | NULL    |       |
| response_message    | varchar(3000)                         | YES  |     | NULL    |       |
| created_date        | datetime                              | NO   |     | NULL    |       |
| last_modified_date  | datetime                              | NO   |     | NULL    |       |
 --------------------- --------------------------------------- ------ ----- --------- ------- 

CREATE TABLE `requests` (   
`request_id` char(32) NOT NULL,   
`owner` varchar(100) NOT NULL,   
`status` enum('PENDING','ACCEPTED','REJECTED') DEFAULT NULL,   
`work_id` char(32) NOT NULL,   
`response_message` varchar(3000) DEFAULT NULL,   
`created_date` datetime NOT NULL,   
`last_modified_date` datetime NOT NULL,   
PRIMARY KEY (`request_id`),   
UNIQUE KEY `work_id` (`work_id`),   
CONSTRAINT `requests_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`work_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1
  

Я хочу удалить UNIQUE Constraint из work_id . Я выполнил некоторый поиск и выполнил следующие команды.

 SHOW INDEX FROM requests;
 ----------------- ------------ ---------------- -------------- ------------------- ----------- ------------- ---------- -------- ------ ------------ --------- --------------- 
| Table           | Non_unique | Key_name       | Seq_in_index | Column_name       | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
 ----------------- ------------ ---------------- -------------- ------------------- ----------- ------------- ---------- -------- ------ ------------ --------- --------------- 
| requests        |          0 | PRIMARY        |            1 | request_id        | A         |          16 |     NULL | NULL   |      | BTREE      |         |               |
| requests        |          0 | work_id        |            1 | work_id           | A         |          16 |     NULL | NULL   |      | BTREE      |         |               |
 ----------------- ------------ ---------------- -------------- ------------------- ----------- ------------- ---------- -------- ------ ------------ --------- --------------- 
  

И затем выполняется

 ALTER TABLE requests DROP INDEX work_id;
  

Я получаю сообщение об ошибке

ОШИБКА 1553 (HY000): не удается удалить индекс ‘work_id’: требуется ограничение внешнего ключа

Комментарии:

1. Можете ли вы добавить результат SHOW CREATE TABLE requests

2. Я использовал эту инструкцию для вставки таблицы, и ответ был таким: «это то, что вы спросили?» Извините, не уверен в вопросе. CREATE TABLE requests ( request_id CHAR(32) NOT NULL, owner VARCHAR(100) NOT NULL, status ENUM('PENDING','ACCEPTED','REJECTED') NOT NULL, work_id CHAR(32) NOT NULL, response_message VARCHAR(3000), created_date DATETIME NOT NULL, last_modified_date DATETIME NOT NULL, PRIMARY KEY (request_id), UNIQUE (work_id), FOREIGN KEY(work_id) REFERENCES work (work_id) );

3. Я вижу, выполнил команду. Вот результат requests | CREATE TABLE `requests` ( `request_id` char(32) NOT NULL, `owner` varchar(100) NOT NULL, `status` enum('PENDING','ACCEPTED','REJECTED') DEFAULT NULL, `work_id` char(32) NOT NULL, `response_message` varchar(3000) DEFAULT NULL, `created_date` datetime NOT NULL, `last_modified_date` datetime NOT NULL, PRIMARY KEY (`request_id`), UNIQUE KEY `work_id` (`work_id`), CONSTRAINT `requests_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`work_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

4. Я добавил решение

Ответ №1:

Итак, ваша проблема в том, что вы пытаетесь удалить индекс, который используется в Foreign Key ограничении. Таким образом, вы не можете сделать это напрямую. Выполните следующие действия:

  1. Удалите ограничение, requests_ibfk_1 которое является вашим foreign key .
 alter table requests drop foreign key requests_ibfk_1
  
  1. Затем удалите UNIQUE KEY столбец on work_id .
 alter table requests drop index work_id
  
  1. Снова добавьте Foreign Key в столбец work_id .
 alter table requests add CONSTRAINT `requests_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`work_id`)
  

ДЕМОНСТРАЦИЯ

Комментарии:

1. В качестве альтернативы, отключите и включите FKs.

Ответ №2:

Проблема в том, что определение ограничения уникальности удаляет индекс, который обычно создается для внешнего ключа. Но есть другой способ, без повторного создания ограничения внешнего ключа или (временно) отключения проверок (что может привести к ошибкам согласованности).

Сначала добавьте другой индекс для того же столбца (по логическим соображениям, я бы назвал его точно так же, как внешний ключ):

 CREATE INDEX requests_ibfk_1 ON requests(work_id);
  

Теперь вы можете безопасно удалить ограничение уникальности / индекс (поскольку для ограничения внешнего ключа все еще доступен индекс):

 DROP INDEX work_id ON requests;
  

Я надеюсь, что это решит проблему.

Ответ №3:

Как описано в комментарии @Rick James , альтернативой является временное отключение ограничений ключа таблицы, немедленное удаление уникального индекса, а затем последующее включение ключей таблицы. Вот пример для mysql / mariadb :

 ALTER TABLE `<YOUR_TABLE_NAME>` DISABLE KEYS;
ALTER TABLE `<YOUR_TABLE_NAME>` DROP INDEX `<YOUR_UNIQUE_INDEX_NAME>`;
ALTER TABLE `<YOUR_TABLE_NAME>` ENABLE KEYS;