mysql從頭學一 1.0資料型別-字元型別
3.3 字串型別
MySQL 中提供了多種對字元資料的儲存型別,不同的版本可能有所差異。以 5.0 版本為例,
MySQL 包括了 CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和 SET 等多種字串型別。表 3-4 中詳細列出了這些字元型別的比較。
表 3-4 MySQL 中的字元型別
字串型別 |
位元組 |
描述及儲存需求 |
CHAR(M) |
M |
M 為 0~255 之間的整數 |
VARCHAR(M) |
|
M 為 0~65535 之間的整數,值的長度+1 個位元組 |
TINYBLOB |
|
允許長度 0~255 位元組,值的長度+1 個位元組 |
BLOB |
|
允許長度 0~65535 位元組,值的長度+2 個位元組 |
MEDIUMBLOB |
|
允許長度 0~167772150 位元組,值的長度+3 個位元組 |
LONGBLOB |
|
允許長度 0~4294967295 位元組,值的長度+4 個位元組 |
TINYTEXT |
|
允許長度 0~255 位元組,值的長度+2 個位元組 |
TEXT |
|
允許長度 0~65535 位元組,值的長度+2 個位元組 |
MEDIUMTEXT |
|
允許長度 0~167772150 位元組,值的長度+3 個位元組 |
LONGTEXT |
|
允許長度 0~4294967295 位元組,值的長度+4 個位元組 |
VARBINARY(M) |
|
允許長度 0~M 個位元組的變長位元組字串,值的長度+1 個位元組 |
BINARY(M) |
M |
允許長度 0~M 個位元組的定長位元組字串 |
下面將分別對這些字串型別做詳細的介紹。
3.3.1 CHAR 和 VARCHAR 型別
CHAR 和 VARCHAR 很類似,都用來儲存 MySQL 中較短的字串。二者的主要區別在於儲存方式的不同:CHAR 列的長度固定為建立表時宣告的長度,長度可以為從 0~255 的任何值;而 VARCHAR 列中的值為可變長字串,長度可以指定為 0~255(5.0.3 以前)或者 65535(5.0.3 以後)之間的值。在檢索的時候,CHAR 列刪除了尾部的空格,而 VARCHAR 則保留這些空格。下面的例子中通過給表 vc 中的 VARCHAR(4)和 char(4)欄位插入相同的字串來描述這個區別。
(1)建立測試表 vc,並定義兩個欄位 v VARCHAR(4)和 c CHAR(4):
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.16 sec)
(2)v 和 c 列中同時插入字串“ab ”:
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.05 sec)
(3)顯示查詢結果:
mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 4 | 2 |
+-----------+-----------+
1 row in set (0.01 sec)
可以發現,c 欄位的 length 只有 2。給兩個欄位分別追加一個“+”字元看得更清楚:
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
| ab + | ab+ |
+----------------+----------------+
1 row in set (0.00 sec)
顯然,CHAR 列最後的空格在做操作時都已經被刪除,而 VARCHAR 依然保留空格。
3.3.2 BINARY 和 VARBINARY 型別
BINARY 和 VARBINARY 類似於 CHAR 和 VARCHAR,不同的是它們包含二進位制字串而不包含非二進位制字串。在下面的例子中,對錶 t 中的 binary 欄位 c 插入一個字元,研究一下這個字元到底是怎麼樣儲存的。
- 建立測試表 t,欄位為 c BINARY(3):
mysql> CREATE TABLE t (c BINARY(3)); Query OK, 0 rows affected (0.14 sec)
- 往 c 欄位中插入字元“a”:
mysql> INSERT INTO t SET c='a';
Query OK, 1 row affected (0.06 sec)
- 分別用以下幾種模式來檢視 c 列的內容:
mysql> select *,hex(c),c='a',c='a\0',c='a\0\0' from t10;
+------+--------+-------+---------+-----------+
| c | hex(c) | c='a' | c='a\0' | c='a\0\0' |
+------+--------+-------+---------+-----------+
| a | 610000 | 0 | 0 | 1 |
+------+--------+-------+---------+-----------+
1 row in set (0.00 sec)
可以發現,當儲存 BINARY 值時,在值的最後通過填充“0x00”(零位元組)以達到指定的欄位定義長度。從上例中看出,對於一個 BINARY(3)列,當插入時'a'變為'a\0\0'。
3.3.3 ENUM 型別
ENUM 中文名稱叫列舉型別,它的值範圍需要在建立表時通過列舉方式顯式指定,對 1~ 255 個成員的列舉需要 1 個位元組儲存;對於 255~65535 個成員,需要 2 個位元組儲存。最多允許有 65535 個成員。下面往測試表 t 中插入幾條記錄來看看 ENUM 的使用方法。
- 建立測試表 t,定義 gender 欄位為列舉型別,成員為'M'和'F':
mysql> create table t (gender enum('M','F'));
Query OK, 0 rows affected (0.14 sec)
- 插入 4 條不同的記錄:
mysql> INSERT INTO t VALUES('M'),('1'),('f'),(NULL); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from t; +--------+ | gender | +--------+ | M | | M | | F | | NULL | +--------+ 4 rows in set (0.01 sec) |
從上面的例子中,可以看出 ENUM 型別是忽略大小寫的,對'M'、'f'在儲存的時候將它們都轉成了大寫,還可以看出對於插入不在 ENUM 指定範圍內的值時,並沒有返回警告,而是插入了 enum('M','F')的第一值'M',這點使用者在使用時要特別注意。另外,ENUM 型別只允許從值集合中選取單個值,而不能一次取多個值。
3.3.4 SET 型別
Set 和 ENUM 型別非常類似,也是一個字串物件,裡面可以包含 0~64 個成員。根據成員的不同,儲存上也有所不同。
- 1~8 成員的集合,佔 1 個位元組。
- 9~16 成員的集合,佔 2 個位元組。
- 17~24 成員的集合,佔 3 個位元組。
- 25~32 成員的集合,佔 4 個位元組。
- 33~64 成員的集合,佔 8 個位元組。
Set 和 ENUM 除了儲存之外,最主要的區別在於 Set 型別一次可以選取多個成員,而 ENUM 則只能選一個。下面的例子在表 t 中插入了多組不同的成員:
Create table t (col set ('a','b','c','d'); insert into t values('a,b'),('a,d,a'),('a,b'),('a,c'),('a'); mysql> select * from t;
+------+
| col |
+------+
| a,b |
| a,d |
| a,b |
| a,c |
| a |
+------+
5 rows in set (0.00 sec)
SET 型別可以從允許值集合中選擇任意 1 個或多個元素進行組合,所以對於輸入的值只要是在允許值的組合範圍內,都可以正確地注入到 SET 型別的列中。對於超出允許值範圍的值例如('a,d,f')將不允許注入到上面例子中設定的 SET 型別列中,而對於('a,d,a')這樣包含重複成員的集合將只取一次,寫入後的結果為“a,d”,這一點請注意。