Ответ 1
Это поле используется во внешних ключах. Чтобы изменить это поле в MySQL, выполните следующие действия:
- Отбросить все связанные внешние ключи
- Изменить поле
- Восстановить все сброшенные внешние ключи
В моей базе данных MySQL InnoDB с внешними ключами я случайно сделал некоторые из моих первичных ключей, подписанных вместо unsigned, как я хочу, чтобы они были.
Теперь я хочу изменить его с помощью инструкции ALTER TABLE, но она не работает:
ALTER TABLE `users` CHANGE `id` `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT
Ошибка MySQL:
Error on rename of './db_dev/#sql-478_3' to './db_dev/users' (errno: 150)
Я не понимаю, почему. Я работаю с Foreign Keys и пробовал использовать
SET foreign_key_checks = 0;
Заявление перед выполнением ALTER TABLE сверху. Не работает. Примечание. Все мои таблицы по-прежнему пусты. В нем пока нет данных.
Поскольку в базе данных много таблиц, было бы очень сложно удалить все внешние ключи, а затем вручную добавить их снова. (если это должно быть причиной).
Это поле используется во внешних ключах. Чтобы изменить это поле в MySQL, выполните следующие действия:
Возьмите дамп базы данных с помощью команды mysql mysqldump и выполните поиск и добавьте unsigned в любое место, где это необходимо. Затем восстановите дамп в той же базе данных. Перед восстановлением удалите из него все таблицы и выгрузите их.
Попробуйте это ALTER TABLE 'users' MODIFY 'id' UNSIGNED NOT NULL AUTO_INCREMENT'
MySQL Workbench позволит вам это сделать. Вам необходимо убедиться, что вы изменили PRIMARY KEY и все столбцы в каждой таблице, в которой есть ссылка на внешний ключ.
Я нашел, что он работает над несколькими сценариями, YMMV.
Я взял на себя проект, у которого была идентичная проблема с некоторыми первичными ключами, и подписано соответствующее внешнее поле.
Я использовал подход @Devart, но мне удалось автоматизировать весь процесс.
Я смог запросить information_schema
для создания дополнительных операторов SQL, которые я мог бы "вырезать и вставить", а затем запустить.
Сгенерировать инструкции SQL для удаления всех ограничений
SELECT concat('ALTER TABLE ', TABLE_NAME, ' DROP FOREIGN KEY ', CONSTRAINT_NAME, ';')
FROM information_schema.key_column_usage
WHERE CONSTRAINT_SCHEMA = 'YOUR_SCHEMA_NAME'
AND referenced_table_name IS NOT NULL;
Изменить любые столбцы id
, которые необходимо изменить на UNSIGNED
SELECT
CONCAT('ALTER TABLE `', TABLE_NAME, '` CHANGE COLUMN id id INT UNSIGNED NOT NULL AUTO_INCREMENT;')
FROM `COLUMNS`
WHERE
`COLUMN_KEY` = 'PRI' AND
`TABLE_SCHEMA` = 'YOUR_SCHEMA_NAME' AND
`COLUMN_TYPE` NOT LIKE '%unsigned%' AND
`COLUMN_TYPE` LIKE '%int%' AND
`COLUMN_NAME` = 'id';
Изменить внешние поля, указывающие на id
SELECT CONCAT('ALTER TABLE `', kcu.TABLE_NAME, '` CHANGE COLUMN ', kcu.COLUMN_NAME,' ', kcu.COLUMN_NAME, ' INT UNSIGNED ', IF(c.IS_NULLABLE = 'YES', 'NULL', 'NOT NULL'), ';')
FROM `KEY_COLUMN_USAGE` kcu
INNER JOIN `COLUMNS` c
ON
kcu.TABLE_NAME = c.TABLE_NAME AND
kcu.COLUMN_NAME = c.COLUMN_NAME
WHERE
`REFERENCED_COLUMN_NAME` = 'id' AND
`REFERENCED_TABLE_NAME` IN (
SELECT
TABLE_NAME
FROM `COLUMNS`
WHERE
`COLUMN_KEY` = 'PRI' AND
`TABLE_SCHEMA` = 'YOUR_SCHEmA_NAME' AND
`COLUMN_TYPE` NOT LIKE '%unsigned%' AND
`COLUMN_TYPE` LIKE '%int%' AND
`COLUMN_NAME` = 'id'
);
(Обратите внимание, что в этом заявлении все по ошибке ошибочно перепутаны даже если они уже НЕ СУЩЕСТВУЮТ, но это не вызывает никаких проблем)
Вставить все необходимые ограничения
SELECT CONCAT('ALTER TABLE ', rc.`TABLE_NAME` ,' ADD CONSTRAINT ', rc.`CONSTRAINT_NAME`, ' FOREIGN KEY (',kcu.`COLUMN_NAME`,') REFERENCES ', rc.`REFERENCED_TABLE_NAME` ,'(id) ON DELETE ', DELETE_RULE , ' ON UPDATE ' , UPDATE_RULE, ';')
FROM `REFERENTIAL_CONSTRAINTS` rc
INNER JOIN
`KEY_COLUMN_USAGE` kcu
ON rc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
WHERE kcu.CONSTRAINT_SCHEMA = 'api' AND
kcu.`REFERENCED_COLUMN_NAME` = 'id';
Обратите особое внимание на эти операторы SQL, возможно, это необходимо изменить для вашей схемы, например, предполагается, что ваш первичный идентификатор называется "id".
Кроме того, вы должны запустить все 4 из этих операторов, прежде чем запускать любой из их фактического вывода.
Использование MySQL 5.6