MySQL 中 blob 和 text 數(shù)據(jù)類型詳解
前言:?
前面文章我們介紹過一些常用數(shù)據(jù)類型的用法,比如 int、char、varchar 等。一直沒詳細(xì)介紹過 blob 及 text 類型,雖然這兩類數(shù)據(jù)類型不太常用,但在某些場景下還是會用到的。本篇文章將主要介紹 blob 及 text 數(shù)據(jù)類型的相關(guān)知識。
? 1. blob 類型
blob(binary large object) 是一個可以存儲二進(jìn)制文件的容器,主要用于存儲二進(jìn)制大對象,例如可以存儲圖片,音視頻等文件。按照可存儲容量大小不同來分類,blob 類型可分為以下四種:
類型 | 可存儲大小 | 用途 |
TINYBLOB | 0 - 255字節(jié) | 短文本二進(jìn)制字符串 |
BLOB | 0 - 65KB | 二進(jìn)制字符串 |
MEDIUMBLOB | 0 - 16MB | 二進(jìn)制形式的長文本數(shù)據(jù) |
LONGBLOB | 0 - 4GB | 二進(jìn)制形式的極大文本數(shù)據(jù) |
其中最常用的就是 blob 字段類型了,最多可存儲 65KB 大小的數(shù)據(jù),一般可用于存儲圖標(biāo)或 logo 圖片。不過數(shù)據(jù)庫并不適合直接存儲圖片,如果有大量存儲圖片的需求,請使用對象存儲或文件存儲,數(shù)據(jù)庫中可以存儲圖片路徑來調(diào)用。
? 2. text 類型
text 類型同 char、varchar 類似,都可用于存儲字符串,一般情況下,遇到存儲長文本字符串的需求時可以考慮使用 text 類型。按照可存儲大小區(qū)分,text 類型同樣可分為以下四種:
類型 | 可存儲大小 | 用途 |
TINYTEXT | 0 - 255字節(jié) | 一般文本字符串 |
TEXT | 0 - 65 535字節(jié) | 長文本字符串 |
MEDIUMTEXT | 0 - 16 772 150字節(jié) | 較大文本數(shù)據(jù) |
LONGTEXT | 0 - 4 294 967 295字節(jié) | 極大文本數(shù)據(jù) |
不過在日常場景中,存儲字符串還是盡量用 varchar ,只有要存儲長文本數(shù)據(jù)時,可以使用 text 類型。對比 varchar ,text 類型有以下特點(diǎn):
text 類型無須指定長度。
若數(shù)據(jù)庫未啟用嚴(yán)格的 sqlmode ,當(dāng)插入的值超過 text 列的最大長度時,則該值會被截斷插入并生成警告。
text 類型字段不能有默認(rèn)值。
varchar 可直接創(chuàng)建索引,text 字段創(chuàng)建索引要指定前多少個字符。
text 類型檢索效率比 varchar 要低。
下面我們來具體測試下 text 類型的使用方法:
#?創(chuàng)建測試表?字符集是?utf8
mysql>?show?create?table?tb_text\G
***************************?1.?row?***************************
???????Table:?tb_text
Create?Table:?CREATE?TABLE?`tb_text`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT?COMMENT?'主鍵',
??`a`?tinytext,
??`b`?text,
??`c`?varchar(255)?DEFAULT?NULL,
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8
#?創(chuàng)建索引測試?發(fā)現(xiàn)text類型必須指定前綴長度
mysql>?alter?table?tb_text?add?index?idx_a?(a);
ERROR?1170?(42000):?BLOB/TEXT?column?'a'?used?in?key?specification?without?a?key?length
mysql>?alter?table?tb_text?add?index?idx_b?(b);?
ERROR?1170?(42000):?BLOB/TEXT?column?'b'?used?in?key?specification?without?a?key?length
mysql>?alter?table?tb_text?add?index?idx_c?(c);
Query?OK,?0?rows?affected?(0.04?sec)
Records:?0??Duplicates:?0??Warnings:?0
mysql>?alter?table?tb_text?add?index?idx_b?(b(10));
Query?OK,?0?rows?affected?(0.06?sec)
Records:?0??Duplicates:?0??Warnings:?0
#?插入數(shù)據(jù)測試(repeat函數(shù)用于生成重復(fù)數(shù)據(jù))
#?正常插入
mysql>?insert?into?tb_text??(a,b,c)?values?(repeat('hello',3),repeat('hello',3),repeat('hello',3));
Query?OK,?1?row?affected?(0.01?sec)
#?插入英文字符超標(biāo)
mysql>?insert?into?tb_text??(a)?values?(repeat('hello',52));
Query?OK,?1?row?affected,?1?warning?(0.01?sec)
mysql>?show?warnings;
+---------+------+----------------------------------------+
|?Level???|?Code?|?Message????????????????????????????????|
+---------+------+----------------------------------------+
|?Warning?|?1265?|?Data?truncated?for?column?'a'?at?row?1?|
+---------+------+----------------------------------------+
1?row?in?set?(0.00?sec)
#?插入中文超標(biāo)
mysql>??insert?into?tb_text??(a)?values?(repeat('你好',100));
Query?OK,?1?row?affected,?1?warning?(0.02?sec)
mysql>?show?warnings;
+---------+------+----------------------------------------+
|?Level???|?Code?|?Message????????????????????????????????|
+---------+------+----------------------------------------+
|?Warning?|?1265?|?Data?truncated?for?column?'a'?at?row?1?|
+---------+------+----------------------------------------+
1?row?in?set?(0.00?sec)
#?查看數(shù)據(jù)?發(fā)現(xiàn)數(shù)據(jù)有所截取?tinytext?類型最多存儲255字節(jié)數(shù)據(jù)
mysql>?select?*?from?tb_text;
+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------+-----------------+
|?id?|?a???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????|?b???????????????|?c???????????????|
+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------+-----------------+
|??1?|?hellohellohello?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????|?hellohellohello?|?hellohellohello?|
|??2?|?hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello?|?NULL????????????|?NULL????????????|
|??3?|?你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你??????????????????????????????????????????????????????????????????????????????????????|?NULL????????????|?NULL????????????|
+----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------+-----------------+
3?rows?in?set?(0.00?sec)通過以上測試,我們注意到,text 類型可存儲容量是以字節(jié)為單位而不是字符。例如 tinytext 最多存儲 255 個字節(jié)而不是 255 個字符,在 utf8 字符集下,一個英文字母或數(shù)字占用一個字節(jié),而一個中文漢字占用三個字節(jié)。也就是說 tinytext 最多存儲 255/3=85 個漢字,text 最多存儲 65535/3=21845 個漢字。而 varchar(M) 中的 M 指的是字符數(shù),一個英文、數(shù)字、漢字都是占用一個字符,即 tinytext 可存儲的大小并不比 varchar(255) 多。
總結(jié):
本篇文章介紹了 blob 及 text 字段類型相關(guān)知識。雖然數(shù)據(jù)庫規(guī)范中一般不推薦使用 blob 及 text 類型,但由于一些歷史遺留問題或是某些場景下,還是會用到這兩類數(shù)據(jù)類型的。這篇文章僅當(dāng)做個記錄了,使用到的時候可以參考下。
推薦閱讀
(點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)
