Projektując tabele nie zawsze uda nam się przewidzieć wyczerpanie zakresu pól.
Pokażę jak w prosty sposób zwiększyć zakres z pominięciem problemu gdy na pole nałożono klucz obcy.
Poniższe tabele zobrazują cały proces:
CREATE TABLE `tab_1` (
`id` SMALLINT(5) unsigned NOT NULL auto_increment,
`user_id` mediumint(9) unsigned NOT NULL default '0',
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
CREATE TABLE `tab_2` (
`id` SMALLINT(5) unsigned NOT NULL auto_increment,
`tab_1_id` SMALLINT(5) unsigned NOT NULL default '0',
`inf` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `pytanie_id` (`tab_1_id`),
CONSTRAINT `tab_ibfk_1` FOREIGN KEY (`tab_1_id`) REFERENCES `tab_1` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;
Musimy pamiętać, że klucze obce (foreign key) zakładamy tylko na pola o tym samym typie.
Jeżeli jednak potrzebujemy zmienić jedno z pól konsekwentnie drugie też musimy.
Poniżej komunikat konfliktu zaistniałego w momencie zamiany pola id w tabeli tab_1:
ERROR 1025 (HY000): Error on rename of './database/#sql-2997_1' to './database/tab_1' (errno: 150)
Rozwiązanie problemu:
1. Zdjąć klucz obcy.
2. Zmienić typ pola w pierwszej tabeli.
3. Zmienić typ drugiego pola powiązanego kluczem obcym na ten sam co pierwszy.
4. Założyć ponownie klucz.
Kroki w przykładzie:
ALTER TABLE `tab_2` drop foreign key `tab_ibfk_1`;
ALTER TABLE `tab_1` MODIFY id int(10) NOT NULL auto_increment;
ALTER TABLE `tab_2` MODIFY tab_1_id int(10) NOT NULL default '0';
ALTER TABLE `tab_2` ADD CONSTRAINT `tab_ibfk_1`
FOREIGN KEY (`tab_1_id`) REFERENCES `tab_1` (`id`) ON DELETE CASCADE;
Sprawdzamy:
SHOW CREATE TABLE tab_1G
*************************** 1. row ***************************
Table: tab_1
Create Table: CREATE TABLE `tab_1` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` mediumint(9) unsigned NOT NULL DEFAULT '0',
`datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci
1 row in set (0.00 sec)
SHOW CREATE TABLE tab_2G
*************************** 1. row ***************************
Table: tab_2
Create Table: CREATE TABLE `tab_2` (
`id` smallint(5) NOT NULL AUTO_INCREMENT,
`tab_1_id` int(10) NOT NULL DEFAULT '0',
`inf` varchar(20) COLLATE utf8_polish_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `pytanie_id` (`tab_1_id`),
CONSTRAINT `tab_ibfk_1` FOREIGN KEY (`tab_1_id`) REFERENCES `tab_1` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci
1 row in set (0.00 sec)
Działa, miłej zabawy.
Dobrą lekturą jest: http://dev.mysql.com/doc/refman/5.0/en/alter-table.html