今天技術討論群里 “一切隨遇而安”同學看書時出現一個疑問,一個MySQL的表中到底可以有多少個欄位?帶著這個疑問,我們展開了探討,也接著討論了一個單欄位長度的問題,
1. 官方檔案說明
官方檔案的內容如下,主要意思是欄位個數限制達不到理想的4096個,且和欄位型別有關,innodb引擎的欄位上限是1017,,

2. 測驗表欄位數限制
2.1 測驗innodb引擎表
因官方檔案介紹了innodb表欄位限制是1017,因此可以寫程式進行模擬,思路如下:
a) 創建一張1個 char(1) 型別的innodb表
b) 回圈往該表新增欄位 直至報錯
我使用的是python 腳本進行測驗,腳本如下:
#!/usr/bin/python # coding=utf-8 import pymysql as mdb import os sor_conn = mdb.connect(host='127.0.0.1',port=3306,user='root',passwd='123456') sor_cur = sor_conn.cursor() v_sql_d = "drop table if exists test.test_c ;" # 為了程式重復執行,添加判斷 sor_cur.execute(v_sql_d) sor_conn.commit() v_sql_c = "create table test.test_c(c1 char(1)) engine=innodb;" sor_cur.execute(v_sql_c) sor_conn.commit() v_id=2 while v_id<50000: v_sql_add_c = " alter table test.test_c add c%d char(1);"%(v_id) try: sor_cur.execute(v_sql_add_c) sor_conn.commit() except mdb.Error,e: v_cnt = v_id - 1 print "Mysql Error %d: %s" % (e.args[0], e.args[1]) print "MySQL has a limit of %d" %(v_cnt) break v_id = v_id + 1 sor_conn.close()
運行結果如下:
[root@testdb python_pro]# python test_column.py Mysql Error 1117: Too many columns MySQL has a limit of 1017
在SQLyog客戶端手動驗證也是同樣的結果
因此,官方檔案中介紹的MySQL innodb引擎表最多有1017個欄位,
2.2 測驗MYISAM引擎表
因為MySQL中另一種MYISAM引擎的表在MySQL5.7版本之前也是非常重要的存盤引擎,只是后續版本使用越來越少,但是 還是有必要測驗一番,
程式思路與測驗innodb是均一致,只是將表的引擎進行修改,如下:
#!/usr/bin/python # coding=utf-8 import pymysql as mdb import os import datetime import time sor_conn = mdb.connect(host='127.0.0.1',port=3306,user='root',passwd='123456') sor_cur = sor_conn.cursor() v_sql_d = "drop table if exists test.test_c ;" sor_cur.execute(v_sql_d) sor_conn.commit() v_sql_c = "create table test.test_c(c1 char(1))engine=MYISAM ;" sor_cur.execute(v_sql_c) sor_conn.commit() v_id=2 while v_id<50000: v_sql_add_c = " alter table test.test_c add c%d char(1);"%(v_id) try: sor_cur.execute(v_sql_add_c) sor_conn.commit() except mdb.Error,e: v_cnt = v_id - 1 print "Mysql Error %d: %s" % (e.args[0], e.args[1]) print "MySQL has a limit of %d" %(v_cnt) break v_id = v_id + 1 sor_conn.close()
運行結果如下:
[root@testdb python_pro]# python test_column.py Mysql Error 1117: Too many columns MySQL has a limit of 2598
也就是說MySQL中MyISAM引擎表最多可以存2598個欄位,
3. 測驗欄位長度限制
大家都知道的一個知識是在MySQL中一行除了blob及text類的大欄位之外,其余欄位的長度之和不能超過65535,那么這個是確定的么,因此再次做一次測驗,
3.1 測驗UTF8字符集
創建一個只有一個欄位的表,欄位長度為65535 結果居然報錯了,提示最大長度只能是21845,也就是65535/3的量,
/* 測驗單欄位長度 上限*/ CREATE TABLE test_c1( c1 VARCHAR(65535) ) ENGINE=INNODB CHARACTER SET utf8; /* 執行結果 */ 錯誤代碼: 1074 Column length too big for column 'c1' (max = 21845); use BLOB or TEXT instead
但是改為21845依舊報錯,原因你仔細品(提示varchar)
CREATE TABLE test_c1( c1 VARCHAR(21845) ) ENGINE=INNODB CHARACTER SET utf8; /* 執行結果依舊報錯 */ 錯誤代碼: 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
那,在減小一位試試
CREATE TABLE test_c1( c1 VARCHAR(21844) ) ENGINE=INNODB CHARACTER SET utf8; /* 終于成功了*/ 查詢:create table test_c1( c1 varchar(21844) ) engine=innodb character set utf8 共 0 行受到影響
有圖有真相

3.2 測驗latin字符集
因為utf8編碼占3位,因此最大長度只能是21845(-1),那么latin字符集是不是就能達到65535了
測驗如下
CREATE TABLE test_c1( c1 VARCHAR(65535) ) ENGINE=INNODB CHARACTER SET latin1 /* 結果依舊失望 */ 錯誤代碼: 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
在想想上面的情況,一直減下去,發現65532即可正常(原因你繼續品就明白了)
CREATE TABLE test_c1( c1 VARCHAR(65532) ) ENGINE=INNODB CHARACTER SET latin1; /* 終于成功了 */ <n>查詢:create table test_c1( c1 varchar(65532) ) engine=innodb character set latin1 共 0 行受到影響
給真相

3. 小結
實踐出真知,任何人說的知識點都要思考,必要的時候自己檢驗一番,
表欄位限制

表欄位長度限制

在此知識給個匆忙的小結,其中原因不懂的可以查看官方檔案,也是詳細的測驗,也可以加群一起討論,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/61042.html
標籤:MySQL
