今天有乙個朋友問我乙個mysql的建表問題,問題的現象是建立表失敗,根據他的反饋,問題比較奇怪,
create table ***
..此處省略260多個字段
`***xisallowin` varchar(4) collate utf8_bin default null comment 'xx是否准入(是,否)',
`***xisallowin` varchar(30) collate utf8_bin default null comment '理財-准入',
primary key (`serialno`),
) engine=innodb default charset=utf8 collate=utf8_bin comment='???????」3èˉ·?????ˉ';
是的,你沒有看錯,還有亂碼,根據朋友反饋的現象是在生產環境可以建立成功,但是測試環境建立失敗。
報錯資訊為:
error 1118 (42000): row size too large (> 8126). changing some
columns to text or blob or using row_format=dynamic or
row_format=compressed may help. in current row format, blob prefix of
768 bytes is stored inline.
我把文字拷貝到本地,想復現,結果因為亂碼直接執行失敗,對於這種情況,還是同事幫我做了下問題過濾,採用如下的方式即可把注釋刪除。
cat a.sql |sed 's/comment'.*'/,/g'
所以省事了不少,我就來繼續分析這個問題。一般來說這個錯誤看起來是單行的資料超出限制了,因為mysql裡面每行的資料有乙個65535的限制,想必是這個原因吧。
但是朋友反饋是沒有超出這個限制的,根據裡面的字元型別做計算,發現確實沒有達到65535.
所以這個問題就微妙起來,我們來說說幾種解決方式。
解決方式1:
修改儲存引擎,設定為myisam
key `idx_customername` (`customername`)
) engine=myisam default charset=utf8 collate=utf8_bin;
"c.sql" 276l, 16070c written
mysql> source c.sql
query ok, 0 rows affected (0.07 sec)
myisam有3种行儲存格式:fixed/dynamic/compressed,innodb在這個基礎上增加了barracuda的格式。
5.7中的預設引數設定如下:
mysql> show variables like '%format';
| variable_name | value |
| binlog_format | row |
| date_format | %y-%m-%d |
| datetime_format | %y-%m-%d %h:%i:%s |
| default_week_format | 0 |
| innodb_default_row_format | dynamic |
| innodb_file_format | barracuda |
| time_format | %h:%i:%s |
7 rows in set (0.00 sec)
所以現在的問題差異就在於myisam和innodb。
共享表空間的格式為antelope,在5.5中預設就是這個格式。
解決方式2;
這個問題我做了一些測試。對比了字符集,row_format的設定。
) engine=innodb row_format=dynamicdefault charset=utf8 collate=utf8_bin;
"c.sql" 276l, 16090c written
mysql> source c.sql
error 1118 (42000): row size too large (> 8126). changing some
columns to text or blob may help. in current row format, blob p
) engine=innodb row_format=compactdefault charset=utf8 collate=utf8_bin;
"c.sql" 276l, 16090c written
mysql> source c.sql
error 1118 (42000): row size too large (> 8126). changing some
columns to text or blob or using row_format=dynamic or
row_format=compressed may help. in current row format, blob prefix of
768 bytes is stored inline.
) engine=innodb default charset=latin1;
"c.sql" 276l, 16056c written
mysql> source c.sql
error 1118 (42000): row size too large (> 8126). changing some
columns to text or blob may help. in current row format, blob prefix of 0
bytes is stored inline.
得到的乙個初步結論就是先設定innodb_strict_mode為off,預設5.7是開啟的,當然從mysql5.5版本開始,可以開啟innodb嚴格檢查模式,如果採用了頁資料壓縮功能後,建議是開啟該功能。在建立表,更改表和建立索引時,如果寫法有錯誤,不會有警告資訊,而是直接丟擲錯誤,這樣就可直接將問題扼殺在搖籃裡。
當然這個裡的這個問題現象確實比較糾結。
解決方法3:
從表結構設計入手,盡可能拆分這個表的邏輯,把它拆分為多個表。乙個表的字段數盡可能不要太多。資料庫、表數量盡可能少;資料庫一般不超過50個,每個資料庫下,資料表數量一般不超過500個(包括分割槽表);可以很明顯看出這個表的設計就是根據業務的需求開始垂直擴充套件,其實可以拆分出乙個邏輯表,邏輯資料很容易持續擴充套件,而不是在字段層面來不斷擴充套件。
mysql 8 0 19 建立表失敗原因
mysql 版本號8.0.19 檢視mysql 版本的sql select version 執行建立表sql報錯,大家可以看一下錯誤日誌,先猜想一下錯誤原因 建立表時,表名和欄位名不需要新增單引號 正確sql如下 create table job info id bigint 20 not null...
mysql複製表結構建立新錶
最近由於資料庫資料日增長量較大,某些不到乙個月已經達到了百萬級資料量,根據需要進行散表。後台將每月新資料insert新錶,因此資料庫要定期建立新錶。涉及到了mysql 定時任務等一系列知識。關於mysql複製表結構建立對應新錶,要求是將按月建立新錶,新錶名為原表名加上日期。如 原表game cent...
mysql中用查詢結果建立新錶
在mysql中可以把已經存在的表直接通過命令複製為另乙個表 方法1 create table mmm select from bbb 注意 這條命令要求mmm這個表在資料庫中不存在 這條命令可以建立新錶mmm並且bbb中的表結構以及資料和mmm完全一樣mysql insert,也可以匯出部分字段 c...