1. 程式人生 > 其它 >MySQL 中 blob 和 text 資料型別詳解

MySQL 中 blob 和 text 資料型別詳解

前言:

前面文章我們介紹過一些常用資料型別的用法,比如 int、char、varchar 等。一直沒詳細介紹過 blob 及 text 型別,雖然這兩類資料型別不太常用,但在某些場景下還是會用到的。本篇文章將主要介紹 blob 及 text 資料型別的相關知識。

1. blob 型別

blob(binary large object) 是一個可以儲存二進位制檔案的容器,主要用於儲存二進位制大物件,例如可以儲存圖片,音視訊等檔案。按照可儲存容量大小不同來分類,blob 型別可分為以下四種:

型別 可儲存大小 用途
TINYBLOB 0 - 255位元組 短文字二進位制字串
BLOB 0 - 65KB 二進位制字串
MEDIUMBLOB 0 - 16MB 二進位制形式的長文字資料
LONGBLOB 0 - 4GB 二進位制形式的極大文字資料

其中最常用的就是 blob 欄位型別了,最多可儲存 65KB 大小的資料,一般可用於儲存圖示或 logo 圖片。不過資料庫並不適合直接儲存圖片,如果有大量儲存圖片的需求,請使用物件儲存或檔案儲存,資料庫中可以儲存圖片路徑來呼叫。

2. text 型別

text 型別同 char、varchar 類似,都可用於儲存字串,一般情況下,遇到儲存長文字字串的需求時可以考慮使用 text 型別。按照可儲存大小區分,text 型別同樣可分為以下四種:

型別 可儲存大小 用途
TINYTEXT 0 - 255位元組 一般文字字串
TEXT 0 - 65 535位元組 長文字字串
MEDIUMTEXT 0 - 16 772 150位元組 較大文字資料
LONGTEXT 0 - 4 294 967 295位元組 極大文字資料

不過在日常場景中,儲存字串還是儘量用 varchar ,只有要儲存長文字資料時,可以使用 text 型別。對比 varchar ,text 型別有以下特點:

  • text 型別無須指定長度。
  • 若資料庫未啟用嚴格的 sqlmode ,當插入的值超過 text 列的最大長度時,則該值會被截斷插入並生成警告。
  • text 型別欄位不能有預設值。
  • varchar 可直接建立索引,text 欄位建立索引要指定前多少個字元。
  • text 型別檢索效率比 varchar 要低。

下面我們來具體測試下 text 型別的使用方法:

# 建立測試表 字符集是 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

# 建立索引測試 發現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

# 插入資料測試(repeat函式用於生成重複資料)
# 正常插入
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)
# 插入英文字元超標
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)
# 插入中文超標
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)
# 檢視資料 發現數據有所擷取 tinytext 型別最多儲存255位元組資料
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 型別可儲存容量是以位元組為單位而不是字元。例如 tinytext 最多儲存 255 個位元組而不是 255 個字元,在 utf8 字符集下,一個英文字母或數字佔用一個位元組,而一箇中文漢字佔用三個位元組。也就是說 tinytext 最多儲存 255/3=85 個漢字,text 最多儲存 65535/3=21845 個漢字。而 varchar(M) 中的 M 指的是字元數,一個英文、數字、漢字都是佔用一個字元,即 tinytext 可儲存的大小並不比 varchar(255) 多。

總結:

本篇文章介紹了 blob 及 text 欄位型別相關知識。雖然資料庫規範中一般不推薦使用 blob 及 text 型別,但由於一些歷史遺留問題或是某些場景下,還是會用到這兩類資料型別的。這篇文章僅當做個記錄了,使用到的時候可以參考下。

作者:MySQL技術
出處:https://www.cnblogs.com/kunjian/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
如果文中有什麼錯誤,歡迎指出。以免更多的人被誤導。有需要溝通的,可以站內私信,文章留言,或者關注『MySQL技術』公眾號私信我。一定盡力回答。