2012-05-31 17 views
11

W mojej bazie danych MySQL InnoDB z kluczami obcymi przez przypadek niektóre z moich kluczy podstawowych zostały podpisane zamiast niepodpisane, tak jak chcę, aby były.Jak zmienić klucz podstawowy MySQL z podpisu na niepodpisany?

Teraz chcę zmienić go z ALTER TABLE, ale to nie działa:

ALTER TABLE `users` CHANGE `id` `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT 

MySQL Error:

Error on rename of './db_dev/#sql-478_3' to './db_dev/users' (errno: 150) 

Nie rozumiem dlaczego. Pracuję z kluczami obcymi i próbuję użyć oświadczenia przed wykonaniem tabeli ALTER od góry. To też nie działa. Uwaga: Wszystkie moje stoły są nadal puste. Nie ma jeszcze żadnych danych.

Ponieważ baza danych zawiera wiele tabel, dużo pracy wymagałoby upuszczenie wszystkich kluczy obcych, a następnie ręczne dodanie ich ponownie. (jeśli to powód).

Odpowiedz

9

To pole jest stosowany w kluczu obcym (ów). Aby zmienić tego pola w MySQL, należy wykonać następujące kroki:

  • Odrzuć wszystkie związane z kluczy obcych
  • Zmienić pole
  • Odtworzenie wszystkich spadła klucze obce
+0

Dzięki. To działa, ale jest obowiązkiem. – Norwald2

+0

Tak, jest. Możesz spróbować zmienić nazwę kolumny przy pomocy refaktoryzacji w [dbForge Studio for MySQL] (http://www.devart.com/dbforge/mysql/studio/); zrobi to automatycznie (w Eksploratorze bazy danych). – Devart

+0

Użyłem tego podejścia i napisałem scenariusz całego procesu, zobacz odpowiedź https://stackoverflow.com/a/47169383/1241791 – Sam

1

Spróbuj
ALTER TABLE 'users' MODIFY 'id' UNSIGNED NOT NULL AUTO_INCREMENT'

+0

też nie działa. – Norwald2

5

Zrób zrzut bazy danych przy użyciu Polecenie mysql mysqldump i wyszukaj i dodaj unsigned w każdym miejscu, gdzie jest to wymagane. Następnie przywróć zrzut do tej samej bazy danych. Przed przywróceniem usuń wszystkie tabele i zrzuć je.

+0

Znacznie prostsze niż upuszczanie obcych kluczy. (jeśli możesz to zrobić) – AntonioCS

+0

Brak konieczności ponownego tworzenia wszystkich kluczy zagranicznych zaoszczędził mi wiele czasu. –

0

MySQL Workbench pozwoli ci to zrobić. Musisz upewnić się, że zmieniasz klucz podstawowy PRIMARY i wszystkie kolumny w każdej tabeli, do której przypisano odwołanie do klucza obcego.

Znalazłem go do pracy w wielu scenariuszach, YMMV.

0

Przejąłem projekt, w którym podpisano identyczne wydanie niektórych kluczy podstawowych i podpisano również powiązane pole obce.

Użyłem podejścia @Devart, ale udało mi się zautomatyzować cały proces. Udało mi się przetestować information_schema, aby wygenerować dodatkowe instrukcje SQL, które można "wyciąć i wkleić", a następnie uruchomić.

Generowanie SQL upuścić wszystkie ograniczenia

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; 

zmieniać żadnych id kolumn, które muszą być zmienione na 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'; 

Alter pola zagraniczne kierujące do 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' 
); 

(Uwaga: w tym oświadczeniu, wszystkie są zmieniane być niepodpisany przez pomyłkę nawet jeśli są one już UNSIGNED ale nie powoduje to żadnych problemów)

ponownie włożyć wszystkie wymagane ograniczenia

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'; 

Zwracaj szczególną uwagę na te instrukcje SQL, może to wymagać modyfikacji dla twojego schematu, na przykład zakłada, że ​​Twój podstawowy identyfikator nosi nazwę "id".

Należy również uruchomić wszystkie 4 z tych instrukcji, PRZED uruchomieniem dowolnego z ich rzeczywistych wyników.

Używanie MySQL 5.6

Powiązane problemy