今天開發在導入數據的時候報一個錯誤:node
Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
1.垂直表字段拆分或者大字段合併(大字段最多不超過768,業務進行合併+拆分),divide your table into small ones. If one table contain more than 10 text colums, and the data contain is a little bit long. this error will be thrown out.mysql
2.修改表的存儲引擎,modify InnoDB to MyISAM.sql
3.修改row_format爲COMPRESSED或者DYNAMIC,固然前提需保證innodb_file_format =Barracuda.數據庫
但爲何會出現上面的解釋?ide
經過查詢發現爲innodb的一個限制:優化
咱們知道innodb的頁塊大小默認爲16kb,表中數據是存放在B-tree node的頁塊中,但若是表中一行的數據長度超過了16k,這時候就會出現行溢出,溢出的行是存放在另外的地方,存放該溢出數據的頁叫uncompresse blob page。this
innodb採用聚簇索引的方式把數據存放起來,即B+樹結構,所以每一個頁塊中至少有兩行數據,不然就失去了B+樹的意義(每個頁中只有一條數據,整個樹成爲了一條雙向鏈表),這樣就得出了一行數據的最大長度就限制爲了8k。spa
當插入的一行數據不能在一個數據頁塊中存放時,爲了保證該頁至少能存放兩行數據,innodb將會自動部分數據溢出到另外頁中,一部分數據將存放在數據頁塊中,其大小爲該列的前768字節,同時接着還有偏移指向溢出頁。設計
如上面所說大字段的前768字節會存放在數據頁塊中,那麼若是有10個大字段(如varchar(1000),text,blob同varchar一樣存儲前768字節),一樣會超過一行數據8k的限制(10768<8000,11768>8000)。若是插入的值超過8000字節,則會報錯(BLOB或TEXT同理):code
明白了是怎麼一回過後,就能夠解決出現問題了:
從上面也能夠看出,在mysql innodb存儲引擎表收到頁塊大小,數據以B+樹的方式組織數據,致使單行數據不能超過8k,從而影響了表中大字段數據類型varchar,text,blob個數限制,在16k頁塊大小下,最好不要超過10個,在表設計中須要注意這個限制。
在innodb plugin的版本中,mysql引入了新的文件格式:barracuda,梭魚;該文件格式中擁有兩種新的行記錄:compressed,dynamic,這兩鍾格式對於BLOB數據徹底採用行溢出方式,在數據頁中只佔用20字節用於指向溢出頁。
Antelope是innodb-base的文件格式, Barracude是innodb-plugin後引入的文件格式,同時Barracude也支持Antelope文件格式。二者區別在於:
文件格式
Antelope(Innodb-base)
支持行格式ROW_FORMAT=COMPACTROW_FORMAT=REDUNDANT特性 Compact和redumdant的區別在就是在於首部的存存內容區別。compact的存儲格式爲首部爲一個非NULL的變長字段長度列表,redundant的存儲格式爲首部是一個字段長度偏移列表(每一個字段佔用的字節長度及其相應的位移)。在Antelope中對於變長字段,低於768字節的,不會進行overflow page存儲,某些狀況下會減小結果集IO.
Barracuda(innodb-plugin)
支持行格式ROW_FORMAT=DYNAMICROW_FORMAT=COMPRESSED特性這二者主要是功能上的區別功能上的。 另外在行裏的變長字段和Antelope的區別是隻存20個字節,其它的overflow page存儲。另外這兩都須要開啓innodb\_file\_per\_table=1(這個特性對一些優化仍是頗有用的)
innodb 通常對應 Compact ,MyISAM 通常對應靜態與動態
mysql中若一張表裏面存在varchar、text以及其變形、blob以及其變形的字段的話,那麼這個表其實也叫動態表,即該表的 row_format是dynamic,就是說每條記錄所佔用的字節是動態的。其優勢節省空間,缺點增長讀取的時間開銷。反之,這張表叫靜態表,該表 row_format爲fixed,即每條記錄佔用字節同樣。優勢讀取快,缺點浪費部分空間,因此,作搜索查詢量大的表通常都以空間來換取時間,設計成靜態表。
修改行格式
ALTER TABLE table_name ROW_FORMAT = DEFAULT
修改過程致使:
fixed--->dynamic: 這會致使CHAR變成VARCHAR
dynamic--->fixed: 這會致使VARCHAR變成CHAR
這裏有一點須要注意,若是要使用壓縮,必定須要先使用innodb_file_format =Barracuda格式,否則沒做用。