2012-05-31 20 views
11

在我的MySQL InnoDB數據庫與外鍵我不小心做了一些我的主鍵簽名,而不是無符號的,因爲我希望他們是。如何將MySQL主鍵從簽名更改爲無符號?

現在我想用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) 

我不明白爲什麼。我正在使用外鍵並嘗試使用

SET foreign_key_checks = 0; 

從上面執行ALTER TABLE之前的語句。也不起作用。 注意:我所有的桌子都是空的。目前還沒有數據。

由於數據庫有很多表,因此放棄所有外鍵然後再手動添加它們將會耗費很多工作。 (如果這應該是原因)。

回答

9

此字段外鍵(S)使用。要在MySQL中修改這個領域,您應執行以下步驟:

  • 刪除所有相關的外鍵
  • 修改場
  • 重建所有下降外鍵
+0

謝謝。這工作,但是是一件苦差事。 – Norwald2

+0

是的。您可以嘗試在[dbForge Studio for MySQL]中重構列重命名(http://www.devart.com/dbforge/mysql/studio/);它會自動執行(在數據庫瀏覽器中)。 – Devart

+0

我使用這種方法並編寫了整個過程,請參閱回答https://stackoverflow.com/a/47169383/1241791 – Sam

1

試試這個
ALTER TABLE 'users' MODIFY 'id' UNSIGNED NOT NULL AUTO_INCREMENT'

+0

不工作要麼。 – Norwald2

5

使用,使數據庫的轉儲mysql命令mysqldump並搜索並在需要的地方添加無符號的每個地方。然後將轉儲恢復到同一個數據庫。還原之前,從中刪除所有表並轉儲它。

+0

比刪除外鍵簡單得多。 (如果你能做到這一點) – AntonioCS

+0

不必重新創建我所有的外鍵爲我節省了很多時間。 –

0

MySQL Workbench會讓你這樣做。您需要確保您更改PRIMARY KEY以及每個具有外鍵引用的表中的所有列。

我發現它可以在很多情況下工作,YMMV。

0

我接手了一個項目,這個項目有一些主鍵已經簽名的問題,並且相關的外地項目也簽了名。

我使用@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被稱爲「ID」。

另外,在運行其任何實際輸出之前,您必須運行這4個語句中的所有語句。

使用MySQL 5.6