前言:?

炎陵網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、成都響應式網(wǎng)站建設公司等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)從2013年開始到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選創(chuàng)新互聯(lián)。
前面寫過一篇介紹int類型的文章,一直想寫一篇介紹字符串字段類型的文章,一直拖著也沒思路要怎么下手。最近多關注了下這方面的文章,決定還是把拖了好久的文章了結(jié)了吧。本篇文章主要會介紹字符串類型char及varchar的用法及區(qū)別。
本文實驗環(huán)境為MySQL 5.7.23版本,存儲引擎為Innodb,sql_mode采用嚴格模式,字符集是utf8。
我們平時使用char類型定義字段時,往往會指定其長度M,即char(M)。其實M指的是字符數(shù),即這個字段最多存儲多少個字符,M可不指定,默認為1,范圍是[0,255],單個字母、數(shù)字、中文等都是占用一個字符。utf8字符集下一個中文字符占用3個字節(jié)。下面我們簡單測試下:
# 假設以如下建表語句創(chuàng)建測試表
CREATE TABLE `char_tb1` (
`col1` char DEFAULT NULL,
`col2` char(5) DEFAULT NULL,
`col3` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 進入數(shù)據(jù)庫查詢建表語句如下 發(fā)現(xiàn)char(M) M可不指定,默認為1
mysql> show create table char_tb1\G
*************************** 1. row ***************************
Table: char_tb1
Create Table: CREATE TABLE `char_tb1` (
`col1` char(1) DEFAULT NULL,
`col2` char(5) DEFAULT NULL,
`col3` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
# 插入數(shù)據(jù) 可以看出M表示保存的最大字符數(shù),字母、數(shù)字、中文等都是占用一個字符
mysql> insert into char_tb1 (col1) values ('a'),('1'),('王'),(']');
Query OK, 4 rows affected (0.01 sec)
mysql> insert into char_tb1 (col1) values ('aa'),('12');
ERROR 1406 (22001): Data too long for column 'col1' at row 1
mysql> select * from char_tb1;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| a | NULL | NULL |
| 1 | NULL | NULL |
| 王 | NULL | NULL |
| ] | NULL | NULL |
+------+------+------+
4 rows in set (0.00 sec)
mysql> insert into char_tb1 (col2) values ('abcd'),('王-123'),('^*123'),('12'),('一二三四五');
Query OK, 5 rows affected (0.01 sec)
mysql> insert into char_tb1 (col2) values ('abcdef');
ERROR 1406 (22001): Data too long for column 'col2' at row 1
mysql> select * from char_tb1;
+------+-----------------+------+
| col1 | col2 | col3 |
+------+-----------------+------+
| a | NULL | NULL |
| 1 | NULL | NULL |
| 王 | NULL | NULL |
| ] | NULL | NULL |
| NULL | abcd | NULL |
| NULL | 王-123 | NULL |
| NULL | ^*123 | NULL |
| NULL | 12 | NULL |
| NULL | 一二三四五 | NULL |
+------+-----------------+------+
9 rows in set (0.00 sec)
# 下面測試發(fā)現(xiàn)M的范圍是[0,255]
mysql> alter table char_tb1 add column col4 char(0);
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table char_tb1 add column col5 char(255);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table char_tb1 add column col5 char(256);
ERROR 1074 (42000): Column length too big for column 'col5' (max = 255); use BLOB or TEXT instead
同樣的,varchar(M)中的的M表示保存的最大字符數(shù),單個字母、數(shù)字、中文等都是占用一個字符。varchar可存儲的長度范圍為0-65535字節(jié),此外,varchar需要使用1或者2個額外字節(jié)記錄字符串的長度:如果列的最大長度小于或等于255字節(jié),則只使用1個字節(jié)表示,否則使用2個字節(jié)。對于Innodb引擎,utf8字符集來說,單個中文字符占用3個字節(jié),所以varchar(M)中的M最大不會超過21845,即M的范圍是[0,21845),并且M必須指定。另外MySQL規(guī)定:單個字段長度不大于65535字節(jié);單行最大限制為65535,這里不包括TEXT、BLOB字段。即單張表中的所有varchar字段定義的長度之和不能大于65535,所以并不是所有varchar(M)字段中的M都可以取到21844,下面我們來驗證下:
# 假設以如下建表語句創(chuàng)建測試表
CREATE TABLE `varchar_tb1` (
`col1` varchar(0) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 查看建表語句 增加字段 發(fā)現(xiàn)M必須指定
mysql> show create table varchar_tb1\G
*************************** 1. row ***************************
Table: varchar_tb1
Create Table: CREATE TABLE `varchar_tb1` (
`col1` varchar(0) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table varchar_tb1 add column col2 varchar;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
# 下面測試證明M最大可取到21844
mysql> CREATE TABLE `varchar_tb2` (col1 varchar(21844));
Query OK, 0 rows affected (0.04 sec)
mysql> CREATE TABLE `varchar_tb3` (col1 varchar(218445));
ERROR 1074 (42000): Column length too big for column 'col1' (max = 21845); use BLOB or TEXT instead
# 下面測試證明單行最大限制為65535字節(jié)
mysql> CREATE TABLE `varchar_tb3` (col1 varchar(10));
Query OK, 0 rows affected (0.04 sec)
mysql> alter table varchar_tb3 add column col2 varchar(21844);
ERROR 1118 (42000): 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
mysql> alter table varchar_tb3 add column col2 varchar(21834);
ERROR 1118 (42000): 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
mysql> alter table varchar_tb3 add column col2 varchar(21833);
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table varchar_tb3\G
*************************** 1. row ***************************
Table: varchar_tb3
Create Table: CREATE TABLE `varchar_tb3` (
`col1` varchar(10) DEFAULT NULL,
`col2` varchar(21833) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
CHAR類型是定長的,MySQL總是根據(jù)定義的字符串長度分配足夠的空間。當保存CHAR值時,在它們的右邊填充空格以達到指定的長度,當檢索到CHAR值時,尾部的空格被刪除掉。
VARCHAR類型用于存儲可變長字符串,存儲時,如果字符沒有達到定義的位數(shù),也不會在后面補空格。但是,由于行是變長的,在UPDATE時可能使行變得比原來更長,這就導致需要做額外的工作。如果一個行占用的空間增長,并且在頁內(nèi)沒有更多的空間可以存儲,在這種情況下InnoDB需要分裂頁來使行可以放進頁內(nèi),這樣會增加碎片。
下面簡單總結(jié)下CHAR與VARCHAR字段類型的適用場景:
CHAR適合存儲很短的字符串,或者所有值都接近同一個長度。例如,CHAR非常適合存儲密碼的MD5值,因為這是一個定長的值。對于經(jīng)常變更的數(shù)據(jù),CHAR也比VARCHAR更好,因為定長的CHAR類型不容易產(chǎn)生碎片。對于非常短的列,CHAR比VARCHAR在存儲空間上也更有效率。例如用CHAR(1)來存儲只有Y和N的值,如果采用單字節(jié)字符集只需要一個字節(jié),但是VARCHAR(1)卻需要兩個字節(jié),因為還有一個記錄長度的額外字節(jié)。
下面這些情況下使用VARCHAR是合適的:字符串很長或者所要存儲的字符串長短不一,差別很大;字符串列的最大長度比平均長度大得多;列的更新很少,所以碎片不是問題。
額外說明下,我們在定義字段最大長度時應該按需分配,提前做好預估。特別是對于VARCHAR字段,有人認為反正VARCHAR數(shù)據(jù)類型是根據(jù)實際的需要來分配長度的,還不如給大一點呢。但事實不是這樣的,比如現(xiàn)在需要存儲一個地址信息,根據(jù)評估,只要使用100個字符就可以了,我們可以使用VARCHAR(100)或VARCHAR(200)來存儲,雖然它們用來存儲90個字符的數(shù)據(jù),其存儲空間相同,但是對于內(nèi)存的消耗是不同的。更長的列會消耗更多的內(nèi)存,因為MySQL通常會分配固定大小的內(nèi)存塊來保存內(nèi)部值,尤其是使用內(nèi)存臨時表進行排列或者操作時會特別糟糕。所以我們在分配VARCHAR數(shù)據(jù)類型時仍然不能夠太過于慷慨。還是要評估實際需要的長度,然后選擇一個最長的字段來設置字符長度。如果為了考慮冗余,可以留10%左右的字符長度。千萬不能認為VARCHAR是根據(jù)實際長度來分配存儲空間,而隨意的分配長度,或者說干脆使用最大的字符長度。
總結(jié):?
本文分別介紹了CHAR與VARCHAR字段類型的使用方法,并且給出了二者的對比以及適用場景。在實際生產(chǎn)情況,需要具體情況具體分析,合適的才是最好的,希望這篇文章能給到大家參考。
文章題目:CHAR與VARCHAR詳解
分享網(wǎng)址:http://chinadenli.net/article48/gossep.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供App設計、軟件開發(fā)、面包屑導航、Google、營銷型網(wǎng)站建設、自適應網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)