一、为什么你需要了解二进制类型?
在日常开发中,我们经常需要处理:
用户密码哈希值存储
文件二进制内容管理
UUID等特殊标识符
加密数据存储
这时候,CHAR/VARCHAR
就显得力不从心了!今天我们就来揭秘MySQL专门为二进制数据设计的两种类型——BINARY和VARBINARY。
二、核心区别速查表
| 特性 | BINARY | VARBINARY | CHAR/VARCHAR |
|---|---|---|---|
| 存储内容 | 二进制字节 | 二进制字节 | 文本字符 |
| 长度 | 固定(0-255) | 可变(0-65535) | 根据字符集变化 |
| 比较方式 | 逐字节比较 | 逐字节比较 | 按字符集规则比较 |
| 填充 | 用0x00填充 | 不填充 | 空格填充/不填充 |
三、5个必知实战技巧
1. 密码哈希存储最佳实践
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50),-- 存储SHA-256哈希(固定64字节)password_hash BINARY(64) NOT NULL);-- 插入用户(假设密码哈希为SHA256('123456'))INSERT INTO users (username, password_hash)VALUES ('admin',UNHEX('8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92'));-- 插入第二个用户(假设密码哈希为SHA256('password'))INSERT INTO users (username, password_hash)VALUES ('user01',UNHEX('5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8'));-- 查询所有用户(哈希显示为十六进制)SELECTid,username,HEX(password_hash) AS password_hashFROM users;-- 查询所有用户(哈希显示为十六进制)SELECTid,username,HEX(password_hash) AS password_hashFROM users;
2. 高效UUID存储方案
CREATE TABLE orders (-- 16字节UUID比36字符的UUID字符串节省空间order_id BINARY(16) PRIMARY KEY,total DECIMAL(10,2));-- 插入UUID示例INSERT INTO orders VALUES(UNHEX(REPLACE(UUID(), '-', '')), 99.99);-- 查询SELECT HEX(order_id) AS order_id_hex, total FROM orders;
3. 二进制数据查询技巧
-- 创建文件签名表CREATE TABLE files (id INT AUTO_INCREMENT PRIMARY KEY,file_name VARCHAR(255) NOT NULL,file_size BIGINT NOT NULL,file_signature VARBINARY(16) NOT NULL, -- 用于存储文件魔数签名file_content LONGBLOB,upload_time DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;-- 创建索引优化查询ALTER TABLE files ADD INDEX idx_signature (file_signature(8)); -- 只索引前8字节-- 插入PNG文件(签名头:0x89504E470D0A1A0A)INSERT INTO files (file_name, file_size, file_signature)VALUES ('example.png',1024,0x89504E470D0A1A0A);-- 插入PDF文件(签名头:0x25504446)INSERT INTO files (file_name, file_size, file_signature)VALUES ('document.pdf',2048,0x25504446);-- 插入ZIP文件(签名头:0x504B0304)INSERT INTO files (file_name, file_size, file_signature, file_content)VALUES ('archive.zip',4096,0x504B0304,-- 模拟ZIP文件内容(实际使用时替换为真实二进制数据)LOAD_FILE('/tmp/sample.zip'));-- 使用UNHEX函数插入(效果相同)INSERT INTO files (file_name, file_size, file_signature)VALUES ('test.jpg',512,UNHEX('FFD8FFE0') -- JPEG文件签名);-- 查看所有文件的签名(16进制格式)SELECTid,file_name,HEX(file_signature) AS signature_hex,file_size,upload_timeFROM files;-- 结果示例:/*+----+-------------+------------------+-----------+---------------------+| id | file_name | signature_hex | file_size | upload_time |+----+-------------+------------------+-----------+---------------------+| 1 | example.png | 89504E470D0A1A0A | 1024 | 2023-08-21 09:15:33 || 2 | document.pdf| 25504446 | 2048 | 2023-08-21 09:15:45 || 3 | archive.zip | 504B0304 | 4096 | 2023-08-21 09:16:02 || 4 | test.jpg | FFD8FFE0 | 512 | 2023-08-21 09:17:15 |+----+-------------+------------------+-----------+---------------------+*/-- 查找所有PNG文件(匹配完整签名)SELECT *FROM filesWHERE file_signature = 0x89504E470D0A1A0A;-- 查找PDF或ZIP文件(使用IN子句)SELECT file_name, file_sizeFROM filesWHERE file_signature IN (0x25504446, 0x504B0304);-- 查找JPEG文件(使用UNHEX函数)SELECT *FROM filesWHERE file_signature = UNHEX('FFD8FFE0');-- 查找所有ZIP开头文件(匹配前4字节)SELECT *FROM filesWHERE LEFT(file_signature, 4) = 0x504B0304;-- 使用SUBSTRING和HEX组合查询SELECT file_nameFROM filesWHERE HEX(SUBSTRING(file_signature, 1, 4)) = 'FFD8FFE0';
4. 避免踩坑:严格模式设置
-- 防止二进制数据被静默截断SET sql_mode = 'STRICT_TRANS_TABLES';
5. 性能优化:索引前缀
-- 对长二进制数据只索引前20字节ALTER TABLE documents ADD INDEX (file_hash(20));
四、常见问题QA
Q:BINARY和BLOB有什么区别?A:BINARY适合小数据(≤64KB),支持默认值;BLOB适合大文件,8.0+才支持默认值
Q:为什么我的二进制比较结果不符合预期?A:二进制比较是区分大小写的!'A'(0x41)≠ 'a'(0x61)
Q:如何选择固定长度还是可变长度?A:哈希值等固定长度数据用BINARY,其他可变数据用VARBINARY
五、性能对比测试
我们对100万条数据进行了基准测试:
插入速度:VARBINARY ≈ BINARY > VARCHAR
查询速度:BINARY > VARBINARY ≈ VARCHAR
存储空间:VARBINARY最省空间(无填充)
六、扩展阅读
MySQL 8.0官方文档-Binary Types
https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.htmlUUID存储优化方案
https://www.percona.com/blog/store-uuid-optimized-way/
MySQL严格模式详解
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-strict

最后修改时间:2025-06-18 15:38:35
文章转载自程序员极光,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




