2011-05-04 15 views
8

ho creato la tavola da script:errore "Impossibile creare la tabella ..." su come aggiungere FOREIGN KEY

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 

DROP TABLE IF EXISTS `Table1`; 
CREATE TABLE IF NOT EXISTS `Table1` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `parentId` bigint(20) DEFAULT NULL, 
    `name` varchar(1024) NOT NULL, 
    `description` varchar(16384) NOT NULL DEFAULT '', 
    `imageId` bigint(20) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `name` (`name`(255)), 
    KEY `parentId` (`parentId`), 
    KEY `imageId` (`imageId`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ; 


INSERT INTO `Table1` (`id`, `parentId`, `name`, `description`, `imageId`) VALUES 
(0, NULL, 'name1', '', NULL), 
(12, 0, 'name2', '', NULL); 

Poi cerco di aggiungere chiave esterna:

ALTER TABLE `Table1` 
    ADD CONSTRAINT `Table1_ibfk_2` 
    FOREIGN KEY (`parentId`) REFERENCES `Table1` (`id`); 

e ottenere il seguente errore:

ERROR 1005 (HY000): Can't create table 'sandbox.#sql-c28_4c' (errno: 150) 

Cosa c'è che non va?

corro

SHOW ENGINE INNODB STATUS; 

Non ultimo errore FOREIGN KEY segue:

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
110504 22:06:55 Error in foreign key constraint of table sandbox/#sql-c28_61: 

    FOREIGN KEY (`parentId`) REFERENCES `Table1` (`id`): 
Cannot resolve table name close to: 
(`id`) 
------------ 

Ma non mi aiuta a capire ciò che è sbagliato.

Io uso Windows Vista, MySql 5.5.11

UPDATE:

Il problema appare quando l'aggiornamento da MySql 5.0.67.

risposta

4

Sfondo

ERROR 1005 (HY000): Can't create table 'sandbox.#sql-c28_4c' (errno: 150)

Quando comando di MySQL per ALTER TABLE lo fa davvero le seguenti fasi:

  1. copiare i dati dalla tabella esistente ad una nuova tabella temporanea.
  2. alterare la struttura della nuova tabella temporanea
  3. eliminare la vecchia tabella
  4. rinominare la tabella temporanea al old_table_name.

Problema
La tua richiesta sta fallendo nel passaggio 1.
noti che tablenames dei collegamenti a file.
Su tablenames di Linux sono case sensitive

In Windows che non sono case sensitive.

risposta
Dal momento che si sta, ovviamente, con Linux, il caso della tabella che si sono REFERENCES ai bisogni di essere lo stesso caso come nella definizione di quel tavolo, probabilmente tutto in minuscolo.
Si sta utilizzando Windows, quindi la distinzione tra maiuscole e minuscole non dovrebbe essere un problema, forse è lo strumento che si sta utilizzando, ho riscontrato anche questi problemi e l'utilizzo di lettere minuscole per i nomi di tabelle ha risolto i miei problemi.

risposta corretta
Impostare il sistema di variabele

lower_case_table_names=1 

per sbarazzarsi di questo problema.

Nota che se avete lower_case_table_names=2 su Windows, la tua casella di Windoze si trasforma in un sensibile macchina Linux caso per quanto MySQL è interessato!

link
http://dev.mysql.com/doc/refman/5.5/en/identifier-case-sensitivity.html

+0

Siamo spiacenti, ma la tua risposta corretta non è corretta :) Io uso lower_case_table_names = 0, inoltre voglio avere http://bugs.mysql.com/bug.php?id=55222 corretto. E ancora di più: tutto funziona perfettamente con MySql 5.1.56. Downgrade. Nei nomi di file windows non fa distinzione tra maiuscole e minuscole, ma esistono tabelle interne di mysql che memorizzano altri nomi di tabelle e possono essere trattati con distinzione tra maiuscole e minuscole a seconda del valore lower_case_table_names – sergtk

+1

@sergdev, Da documenti: i nomi di tabelle e database vengono archiviati su disco utilizzando il lettera maiuscola specificata nell'istruzione CREATE TABLE o CREATE DATABASE. I confronti tra nomi sono case sensitive. Non si dovrebbe impostare questa variabile su 0 se si sta eseguendo MySQL su un sistema con nomi di file maiuscole e minuscole (come Windows o Mac OS X). Se si impone questa variabile a 0 con --lower-case-table-names = 0 su un file system senza distinzione tra maiuscole e minuscole e si accede a nomi di tabelle MyISAM utilizzando diverse lettere maiuscole, potrebbe verificarsi un danneggiamento dell'indice. ** ** assomiglia alle impostazioni: ** ' lower_case_table_names = 0' ** è il problema ** – Johan

0

Penso che la tua dichiarazione della chiave esterna potrebbe essere sbagliata, a seconda di cosa stavi veramente cercando. Questo sembra dire che 'parentID' da 'Table1' farà riferimento al campo 'id' da 'Table1'.

ALTER TABLE `Table1` 
    ADD CONSTRAINT `Table1_ibfk_2` 
    FOREIGN KEY (`parentId`) REFERENCES `Table1` (`id`); 

Forse provare questo:

ALTER TABLE `Table1` 
    ADD CONSTRAINT `Table1_ibfk_2` 
    FOREIGN KEY (`id`) REFERENCES Parent(`parentId`); 
+0

CHIAVE ESTERA ('parentId') RIFERIMENTI' Table1' ('id'); è quello che voglio Voglio che parentId faccia riferimento alla stessa tabella e abbia uno dei valori di id-column. In realtà questa è una struttura ad albero. – sergtk

+0

Non ero sicuro se fosse quello che volevi, ho pensato che sarebbe stata la soluzione più semplice. –

+0

Questo codice funzionava prima e il problema si presentava solo dopo aver aggiornato la versione? –

1

soluzione trovata.

Il nome della tabella deve essere in minuscolo dopo REFERENCES.

ALTER TABLE `Table1` 
    ADD CONSTRAINT `Table1_ibfk_2` 
    FOREIGN KEY (`parentId`) REFERENCES `table1` (`id`); 

Sembra un bug in MySql 5.5.11.

FI. phpmyadmin non può aggiungere la chiave esterna.

L'esportazione produce anche il nome della tabella in lettere minuscole.

MySql 5.1.56 funziona come previsto.

+0

Sembra davvero un bug: http://bugs.mysql.com/bug.php?id=60229 – Benjamin

+0

È bello aspettarsi che venga corretto. Ora sono tornato a una versione più vecchia. – sergtk

1

Nel mio caso è stato dovuto al fatto che il campo che era un campo di chiave esterna ha avuto un troppo lungo nome, vale a dire. foreign key (some_other_table_with_long_name_id). Prova sth più corto. Il messaggio di errore è un po 'fuorviante in questo caso.

Anche le definizioni dei campi devono essere uguali (prestare attenzione al sottotipo unsigned).

0

ho avuto la stessa eccezione:

[PDOException]                     
    SQLSTATE[HY000]: General error: 1005 Can't create table 'service.#sql-4851_c07' (errno: 150) 

Il problema che ho avuto è stato, il campo volevo fare chiave esterna non è stato permesso di essere NULL :) Dopo ho capito che dovevo farlo permesso per essere nulla, tutto ha iniziato a funzionare.

Ovviamente nella domanda iniziale, non è il caso, volevo solo far sapere agli altri una possibile soluzione.

Problemi correlati