這幾天由於在趕項目進度,也就沒有及時記錄下自己的學習情況 ,在完成項目的這段時間里,碰到了很多問題,在解決問題的過程中學習了不少技巧。
這里就主要介紹一下在mysql數據庫中為表之間建立外鍵時報1005 - Can't create table 'xx' (errno: 150)錯誤的解決方法。
PS:之所以要記錄下來是因為我當時被這個問題困擾了幾個小時。
先奉上我解決問題的時候所參考的博文鏈接:http://yin123.blog.51cto.com/882581/533192/這篇博文介紹了下面這幾個處理可能造成這個錯誤的可疑點。
在mysql中創建外鍵報150錯誤的原因有以下幾點:
1、建立外鍵的兩個字段的類型或者大小沒有嚴格一致,例如,如果一個是INT(10), 那么外鍵也必須設置成INT(10), 而不是 INT(11) 也不能是 TINYINT. 你得使用 ”show create table 表名;“ 命令來查看字段的大小,因為一些查詢瀏覽器有時候把 int(10) 和int(11) 都顯示為integer。另外,你還必須確定兩個字段是否一個為 SIGNED,而另一個又是UNSIGNED, 這兩字段必須嚴格地一致匹配,更多關於signed 和 unsigned 的信息,請參閱:http://www.verysimple.com/blog/?p=57
2、你試圖引用的其中一個外鍵沒有建立起索引,或者不是一個primary key , 如果其中一個不是primary key 的話,你必須為它創建一個索引。
3、外鍵的名字是一個已經存在的一個鍵值了,這個時候,你應該檢查你的數據庫以確保外健名字是唯一的,或者你在鍵名后面加上幾個隨機的字符以測試是否是這個原因。
4、其中一個或者兩個表是MyISAM引擎的表,若想要使用外鍵約束,必須是InnoDB引擎,(實際上,如果兩個表都是MyISAM 引擎的,這個錯誤根本不會發生,但也不會產生外鍵),你可以通過查詢瀏覽器來設置表的引擎類型。
5、你可能設置了ON DELETE SET NULL, 但是相關的鍵的字段又設置成了NOTS NULL 值。你可能通過修改cascade 的屬性值或者把字段屬性設置成 allow null 來搞定這個bug。
6、你可能設置為外鍵設置了一個默認值,如 default=0 。
7、請確定你的Charset 和 Collate 選項在表級和字段級上的一致。
8、在這個關系里面,其中的一個字段是一個混合鍵值中的一個,它沒有自己獨立的索引,這時,你必須為它創建一個獨立的索引。
9、ALTER 聲明中有語法錯誤 。
而我當時對比了建立外鍵聯系的兩個字段的很多地方,發現類型,大小,引擎等等都一致,糾結了很久,最后看到可能是創建外鍵的時候設置了ON DELETE SET NULL這句話,我立馬查看自己創建外鍵的語句,果不其然就是這個原因,因為創建外鍵聯系的這兩個字段都設置了NOT NULL,所以創建外鍵的語句死活通不過,一直報 Can't create table 'xx' (errno: 150)。
學習了,在此做個記錄。