2012年3月5日 星期一

[MySQL] error 1118

今天在批次 create table 時遇到這個問題,
同一批 table 們之前在 Oracle 與 MySQL database 有 create 過,但今天在另新機器的 MySQL 中 create 卻出現這個問題
error 1118: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change 

Create 語法如下:

create table table_name (
column_01 VARCHAR(255),
column_02 VARCHAR(255),
column_03 VARCHAR(255),
column_04 VARCHAR(255),
column_05 VARCHAR(255),
column_06 VARCHAR(255),
column_07 VARCHAR(255),
column_08 VARCHAR(255),
column_09 VARCHAR(255),
column_10 VARCHAR(255),
column_11 VARCHAR(255),
column_12 VARCHAR(255),
column_13 VARCHAR(255),
column_14 VARCHAR(255),
column_15 VARCHAR(255),
column_16 VARCHAR(255),
column_17 VARCHAR(255),
column_18 VARCHAR(255),
column_19 VARCHAR(255),
column_20 VARCHAR(255),
column_21 VARCHAR(255),
column_22 VARCHAR(255),
column_23 VARCHAR(255),
column_24 VARCHAR(255),
column_25 VARCHAR(255),
column_26 VARCHAR(255),
column_27 VARCHAR(255),
column_28 VARCHAR(255),
column_29 VARCHAR(255),
column_30 VARCHAR(255),
column_31 VARCHAR(255),
column_32 VARCHAR(255),
column_33 VARCHAR(255),
column_34 VARCHAR(255),
column_35 VARCHAR(255),
column_36 VARCHAR(255),
column_37 VARCHAR(255),
column_38 VARCHAR(255),
column_39 VARCHAR(255),
column_40 VARCHAR(255),
column_41 VARCHAR(255),
column_42 VARCHAR(255),
column_43 VARCHAR(255),
column_44 VARCHAR(255),
column_45 VARCHAR(255),
column_46 VARCHAR(255),
column_47 VARCHAR(255),
column_48 VARCHAR(255),
column_49 VARCHAR(255),
column_50 VARCHAR(255),
column_51 VARCHAR(255),
column_52 VARCHAR(255),
column_53 VARCHAR(255),
column_54 VARCHAR(255),
column_55 VARCHAR(255),
column_56 VARCHAR(255),
column_57 VARCHAR(255),
column_58 VARCHAR(255),
column_59 VARCHAR(255),
column_60 VARCHAR(255),
column_61 VARCHAR(255),
column_62 VARCHAR(255),
column_63 VARCHAR(255),
column_64 VARCHAR(255),
column_65 VARCHAR(255),
column_66 VARCHAR(255),
column_67 VARCHAR(255),
column_68 VARCHAR(255),
column_69 VARCHAR(255),
column_70 VARCHAR(255),
column_71 VARCHAR(255),
column_72 VARCHAR(255),
column_73 VARCHAR(255),
column_74 VARCHAR(255),
column_75 VARCHAR(255),
column_76 VARCHAR(255),
column_77 VARCHAR(255),
column_78 VARCHAR(255),
column_79 VARCHAR(255),
column_80 VARCHAR(255),
column_81 VARCHAR(255),
column_82 VARCHAR(255),
column_83 VARCHAR(255),
column_84 VARCHAR(255),
column_85 VARCHAR(255),
column_86 VARCHAR(255),
column_87 VARCHAR(255),
column_88 VARCHAR(255),
column_89 VARCHAR(255),
column_90 VARCHAR(255),
column_91 VARCHAR(255),
column_92 VARCHAR(255),
column_93 VARCHAR(255),
column_94 VARCHAR(255),
column_95 VARCHAR(255),
column_96 VARCHAR(255),
column_97 VARCHAR(255),
column_98 VARCHAR(255),
column_99 VARCHAR(255),
column_100 VARCHAR(255),
column_101 VARCHAR(255),
column_102 VARCHAR(255),
column_103 VARCHAR(255),
column_104 VARCHAR(255),
column_105 VARCHAR(255),
column_106 VARCHAR(255),
column_107 VARCHAR(255),
column_108 VARCHAR(255),
column_109 VARCHAR(255),
IDATE date
)



後來查一下才了解原來在 row 的最大長度不能超過65535
Connection 指定編碼為utf8
jdbc:mysql://127.0.0.1:3306/dbname?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&zeroDateTimeBehavior=convertToNull

這個table 總共110個欄位,其中109個是VARCHAR
扣除最後一個 date 欄位,所有 utf-8 的 VARCHAR 型態的欄位總長度= 109 * 255 * 3 = 83385 (bytes)
這樣單一 row 就超過65535了,所以就不行了,錯誤訊息叫我改
啊為什麼之前也在別個 MySQL Database 建過 table 一樣的 create command 卻可以順利建起來?因為之前在 Connection 指定編碼為Bit5,單一字元2Bytes109 * 255 * 2 = 55590,也沒超過65535倒也相安無事
Utf8 and big5 的長度各佔幾bytes的這個說法可能還要再確認一下 

於是請教了 jserv 大大

:   http://lms.xms.com.tw/sam/doc/559 這裡面說 UTF83字節,Big52字節..... 請問這裡的字節是指 bytes?
Jserv: 是的
Jserv: 不過 UTF-8 只是表示方法
    一個中文字要用到 6 bytes 來表示,也不是不可能
    Big5 是固定長度的表示法,而 UTF-8 只說最小表示單元 8-bit
    有興趣可以看看http://www.slideshare.net/jserv/cip-overview2010
Jserv: 要看文化的演變呀
    Unicode 是活的

所以現在有兩條路可以走,一個是改欄位長度,把這些 table 們從 varchar(255) 改回varchar(200),跟(H/MT)一樣,但是這樣影響深遠,C專案要改改程式N專案也要還要重新測過一遍,就不想動。也許以後設計的時候可以加減考慮一下這個部份的彈性。

查了一下MySQL data type
除了 Varchar 以外,還有 TINYTEXT 的長度也是255
於是改用 TINYTEXT 

另外關於 unicode 是活的 這件事,先記下來再來做實驗測一下



 * Reference : 
 *  MySQL 4.0  Data Type reference : 
 * 
 *  MySQL 5.5 Java, JDBC and MySQL Types
 * 
 *  ORACLE Data Type reference : 
 * 
 *  Default Data Type Mappings Used by Oracle SQL Developer
 * 
 *  Data Type and Java-to-Java Type Mappings
 * 
 * 
 * 
 * 
 *