● MySQL Server最多只允許4096個(gè)字段
● InnoDB 最多只能有1000個(gè)字段
● 字段長(zhǎng)度加起來如果超過65535,MySQL server層就會(huì)拒絕創(chuàng)建表
● 字段長(zhǎng)度加起來(根據(jù)溢出頁指針來計(jì)算字段長(zhǎng)度,大于40的,溢出,只算40個(gè)字節(jié))如果超過8126,InnoDB拒絕創(chuàng)建表
其實(shí)MySQL在計(jì)算字段長(zhǎng)度的時(shí)候并不是按照字段的全部長(zhǎng)度來記的。列字段小于40個(gè)字節(jié)的都會(huì)按實(shí)際字節(jié)計(jì)算,如果大于20 * 2=40 字節(jié)就只會(huì)按40字節(jié)。
創(chuàng)建一個(gè)300個(gè)字段長(zhǎng)度類型為varchar(30)的表,在創(chuàng)建時(shí)不會(huì)創(chuàng)建成功。因?yàn)関archar(30)沒有超過20*2,那么總長(zhǎng)度就是300*30=9000 > 8126就會(huì)創(chuàng)建失敗。
創(chuàng)建一個(gè)150個(gè)字段長(zhǎng)度類型為varchar(100)的表可以創(chuàng)建成功。因?yàn)関archar(100) 大于了20*2那么就只會(huì)按40計(jì)算 總長(zhǎng)度就是150*20*2=6000 < 8126 就會(huì)創(chuàng)建成功。
varchar(40) uft8 理論上能建立203列(8126/40) 但是實(shí)際上只建立了 196列
● 表結(jié)構(gòu)中根據(jù)Innodb的ROW_FORMAT的存儲(chǔ)格式確定行內(nèi)保留的字節(jié)數(shù)(20 VS 768),最終確定一行數(shù)據(jù)是否小于8126,如果大于8126,報(bào)錯(cuò)。
MySQL官方手冊(cè)就可以查詢到, 對(duì)于一行記錄最大的限制是65535字節(jié)。為什么是65535?規(guī)定一行數(shù)據(jù)里面字段長(zhǎng)度定義有64k;
有了65535的限制以后還有一個(gè)8126的限制是為什么呢?
MySQL是分兩層的,
MySQL Server層 + 存儲(chǔ)引擎層。
第2個(gè)問題其實(shí)是MySQL除了在Server層做了一次限制還會(huì)在Innodb存儲(chǔ)引擎層在做一次限制。
innodb為了保證B+TREE是一個(gè)平衡樹結(jié)構(gòu),強(qiáng)制要求一條記錄的大小不能超過一個(gè)頁大小的一半。這也就是我們上面看到的第二個(gè)錯(cuò)誤。
下面是innodb B+樹的結(jié)構(gòu),我們可以想象一下二分查找時(shí),一個(gè)頁的只有一條數(shù)據(jù)會(huì)是什么樣子?
每個(gè)頁只有一條數(shù)據(jù)的查找就變成了鏈表查找了。這樣就沒有二分查找的意義了。
而MySQL中默認(rèn)的頁大小是16K,16K的一半是8196字節(jié)減去一些元數(shù)據(jù)信息就得出了8126這個(gè)數(shù)字。
還可以看看
其他文章,謝謝您的閱讀。
網(wǎng)站申明:系本文編輯轉(zhuǎn)載,來源于網(wǎng)絡(luò),目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé),所有權(quán)歸屬原作者。如內(nèi)容、圖片有任何版權(quán)問題,請(qǐng)
聯(lián)系我們刪除。