为什么TEXT不区分大小写,而BLOB严格区分?
技术解析与SQL示例
BLOB
和 TEXT
家族(包括TINYBLOB
/TINYTEXT
, MEDIUMBLOB
/MEDIUMTEXT
, LONGBLOB
/LONGTEXT
)在存储容量上是对应的,它们的核心区别在于对字符集的处理。
•
BLOB
(Binary Large Object - 二进制大对象):• 用于存储二进制数据,如图片、音频、视频文件、序列化的Java对象等。
• 它没有字符集的概念,数据被视为一串纯粹的字节流。
• 因此,它的排序和比较是基于字节的数值进行的,是区分大小写的。
•
TEXT
(文本):• 用于存储长文本数据,如文章内容、JSON文档、日志等。
• 它有字符集的概念(如
utf8mb4
)。• 它的排序和比较是基于该字符集的校对规则 (Collation) 进行的。在大多数默认情况下(如
_ci
后缀的校对规则),是不区分大小写的。
SQL 示例
这个实验将清晰地展示它们在处理大小写和排序时的不同行为。
-- 创建一个用于演示的表
-- 我们使用 utf8mb4 字符集,以及一个不区分大小写的校对规则 utf8mb4_general_ci
CREATE TABLE data_storage_demo (id INT PRIMARY KEY AUTO_INCREMENT,blob_data BLOB,text_data TEXT
) CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;-- 插入两条看起来相似,但大小写不同的数据
INSERT INTO data_storage_demo (blob_data, text_data) VALUES ('Apple', 'Apple');
INSERT INTO data_storage_demo (blob_data, text_data) VALUES ('apple', 'apple');-- 1. 比较查询:看看 'Apple' 能否匹配 'apple'
-- 对于 TEXT,校对规则是不区分大小写的,所以能找到两条记录
SELECT * FROM data_storage_demo WHERE text_data = 'Apple';
-- +----+-----------+-----------+
-- | id | blob_data | text_data |
-- +----+-----------+-----------+
-- | 1 | Apple | Apple |
-- | 2 | apple | apple |
-- +----+-----------+-----------+-- 对于 BLOB,比较是基于字节的,'A' (ASCII 65) 和 'a' (ASCII 97) 是不同的,所以只能找到一条
SELECT * FROM data_storage_demo WHERE blob_data = 'Apple';
-- +----+-----------+-----------+
-- | id | blob_data | text_data |
-- +----+-----------+-----------+
-- | 1 | Apple | Apple |
-- +----+-----------+-----------+-- 2. 排序查询:看看它们的排序顺序
SELECT * FROM data_storage_demo ORDER BY text_data;
-- 对于 TEXT,'Apple' 和 'apple' 在不区分大小写的规则下被认为是相等的,顺序可能不固定
-- (具体顺序取决于MySQL的实现细节)
-- +----+-----------+-----------+
-- | id | blob_data | text_data |
-- +----+-----------+-----------+
-- | 1 | Apple | Apple |
-- | 2 | apple | apple |
-- +----+-----------+-----------+SELECT * FROM data_storage_demo ORDER BY blob_data;
-- 对于 BLOB,排序严格按照字节值,'A' (65) 在 'a' (97) 之前
-- +----+-----------+-----------+
-- | id | blob_data | text_data |
-- +----+-----------+-----------+
-- | 1 | Apple | Apple |
-- | 2 | apple | apple |
-- +----+-----------+-----------+
故事场景:保管“传世画作”与“历史文献”
你(数据库)是这家档案馆的馆长,负责保管人类最重要的文化遗产。今天,你收到了两件珍品。
藏品A:BLOB
— 一幅达芬奇的“传世画作”
这是一幅无价的油画,比如《蒙娜丽莎》。
• 保管方式:
对于这幅画,你最关心的是保持其原始的、物理的、未经任何解读的状态。你把它放进一个真空、恒温、恒湿的密封保险箱里。• 无字符集: 你不会去关心画上的人是男是女,背景是什么颜色,甚至不会去“解读”这幅画。对你来说,它就是一堆精确的、不可更改的颜料分子组合(二进制字节流)。
• 字节比较: 如果有人拿来另一幅画,问你是不是《蒙娜麗莎》,你会用激光扫描仪,逐个像素、逐个分子地进行比对。哪怕只有一个像素的颜色代码不同,你都会判定它们是两幅不同的画。比较是绝对精确和严格的。
• 何时使用它?
当你需要存储那些**不需要被数据库理解其内容,只需原样存取的“原始数据块”**时。• 图片 (
.jpg
,.png
)• 音视频 (
.mp3
,.mp4
)• PDF文档、Zip压缩包
• 任何程序的二进制文件
藏品B:TEXT
— 一部莎士比亚的“历史文献”
这是一部用英文写成的剧本手稿,比如《哈姆雷特》。
• 保管方式:
对于这份手稿,你不仅要保存它,还要能够理解和处理它的内容。你把它存放在一个专门的“语言文献室”里。• 有字符集: 你在保管时,会特别标注:“这是一份‘英文’文献”(指定了字符集
charset
)。这意味着,档案馆的机器人知道如何正确地“阅读”和“理解”上面的每一个字母。• 按语言规则比较: 如果有人问你,馆里有没有关于“Apple”的文献,而手稿上写的是“apple”。档案馆的机器人会根据你设定的“英文(不区分大小写)”校对规则(
collation
),认为“Apple”和“apple”是同一个词,然后把《哈姆雷特》手稿拿给你。排序时,它也会按照语言的字典序来排,而不是看哪个字母的二进制码更小。
• 何时使用它?
当你需要存储大量的、需要被数据库理解和进行文本操作的字符数据时。• 博客文章、新闻内容
• 商品长描述
• 用户评论
• JSON 或 XML 格式的数据
故事总结:
特性 | BLOB (传世画作) | TEXT (历史文献) |
核心数据类型 | 二进制 字符串 (Byte String) | 非二进制 字符串 (Character String) |
字符集概念 | ❌ 没有 | ✅ 有 (如 |
排序与比较 | 基于字节的数值 (区分大小写) | 基于字符集的校对规则 (通常不区分大小写) |
核心比喻 | 一个密封的、内容未知的保险箱 | 一本语言明确、内容可读的档案册 |
一句话总结 | 我存的是“比特流”,我不管内容是啥。 | 我存的是“文字”,我知道这是哪国话。 |
结论:
选择BLOB
还是TEXT
的根本依据是:你要存储的数据,是否需要数据库将其作为“语言文字”来理解和处理?
• 如果是图片、文件等,数据库不需要、也不应该去理解其内容,就用
BLOB
。• 如果是文章、评论等,你希望数据库能进行不区分大小写的搜索、按字典序排序等文本操作,就用
TEXT
。