1. 程式人生 > >操作MySQL出錯提示“BLOB/TEXT column used in key specification without a key length”解決辦法

操作MySQL出錯提示“BLOB/TEXT column used in key specification without a key length”解決辦法

一、問題

pandas物件將DataFrame資料儲存到mysql中時,出現錯誤提示:   BLOB/TEXT column used in key specification without a key length

或者

     在MySQL資料庫中,當MySQL建立新表或者更改已存在表,這個表存在主鍵,並且是unique唯一性約束和索引約束時,或者是在定義一個索引來更改資料表的text欄位操作語句的時候,下面的錯誤資訊很可能會出現,並且經過當前操作命令的完成。錯誤資訊為BLOB或者TEXT欄位使用了未指定鍵值長度的鍵,發生了這樣的錯誤:BLOB/TEXT column 'name' used in key specification without a key length。

       查閱資料後才知道,原來Mysql資料庫對於BLOB/TEXT這樣型別的資料結構只能索引前N個字元。所以這樣的資料型別不能作為主鍵,也不能是UNIQUE的。所以要換成VARCHAR,但是VARCHAR型別的大小也不能大於255,當VARCHAR型別的欄位大小如果大於255的時候也會轉換成小的TEXT來處理。所以也同樣有問題。

       此外,因為MySQL只能將BLOB/TEXT型別欄位設定索引為BLOB/TEXT資料的錢N個字元,因此錯誤常常發生在欄位被定義為TEXT/BLOB型別或者和TEXT/BLOB同質的資料型別,如TINYTEXT,MEDIUMTEXT,LONGTEXT ,TINYBLOB,MEDIUMBLOB 和LONGBLOB,並且當前操作是將這個欄位設定成主鍵或者是索引的操作。在未指定TEXT/BLOB‘鍵長’的情況下,欄位是變動的並且是動態的大小所以MySQL不能夠保證欄位的唯一性。因此當使用TEXT/BLOB型別欄位做為索引時,N的值必須提供出來才可以讓MySQL決定鍵長,但是MySQL不支援在TEXT/BLOB限制,TEXT(88)是不行的。

     當你試圖將資料表中的一個非TEXT或者非BLOB型別如VARCHAR或ENUM的欄位轉換成TEXT/BLOB,同時這個欄位已經被定義了unique限制或者是索引,這個錯誤也會彈出,並且更改資料表的命令會執行失敗

二、原因

出問題的原因是DataFrame物件索引的資料型別是TEXT/BLOB或其從屬的型別,當將其作為mysql中的主鍵的時候,如果這些資料型別缺少明確的長度值,mysql無法保證主鍵的唯一性,因為這個主鍵是一個變數,其長度是動態的。所以當使用 TEXT/BLOB型別的資料作為索引的時候,資料的長度必須提供給mysql,使其能夠明確鍵的長度。但是mysql不支援對TEXT/BLOB長度的限制。

同樣的錯誤也會出現在試圖將非TEXT/BLOB型別的資料列轉換成TEXT/BLOB型別,這些列被定義成獨立的索引。AlterTable命令會失效。

三、解決方法

       解決方案是將unique限制和索引從TEXT/BLOB欄位中移除,或者是設定另一個欄位為主鍵。如果不得不設定成主鍵,而想限制TEXT/BLOB的長度,可以嘗試使用VARCHAR並設定其長度。VARCHAR預設長度是255個字元,並且其長度必須在其宣告之後的右邊括號中設定,例如,VARCHAR(200)將其設定成200個字元長度。

       有時候,即使你在資料表中不使用TEXT/BLOB型別或者同質型別,error1170 也會出現,這個問題出現在當你設定一個VARCHAR欄位為主鍵,但是卻錯誤的設定了長度或者字元數,事實上,VARCHAR只能接受最大為256個字串,但是你錯誤的設定成VARCHAR(512)等一些錯誤的設定,這些錯誤的設定會強制MySQL自動將VARCHAR(512)等轉換成SMALLINT型別,同時這個欄位被設定成primary key ,unique限制或者index索引等,然後執行操作就出現error 1170錯誤,解決問題的方法,為VARCHAR域指定小於256的長度。

mysql #1170錯誤(42000) BLOB/TEXT Column Used in Key Specification Without a Key Length

將DataFrame資料輸出到mysql時強制將索引轉換成VARCHAR並限制其長度,其中的code是索引的標籤:

1 data.to_sql('data',engine,if_exists='replace',dtype={'code':VARCHAR(data.index.get_level_values('code').str.len().max())})

參考:https://www.cnblogs.com/zhangjpn/p/6133793.html 

           https://blog.csdn.net/u012069924/article/details/28858337