一、ENUM类型(单选)
1.ENUM存储原理
sql
-- 创建示例表
CREATE TABLE user (
id INT PRIMARY KEY,
gender ENUM('男','女','未知') -- 实际存储的是数字下标
);
底层存储映射
'男' → 1
'女' → 2
'未知' → 3
2.ENUM的查询方式
sql
SELECT * FROM user WHERE gender = '男';
SELECT * FROM user WHERE gender = 1;
二、SET类型(多选)
1.SET存储原理(位掩码机制)
sql
CREATE TABLE player (
id INT PRIMARY KEY,
hobby SET('读书','游戏','音乐','运动','旅游','美食','电影','购物')
);
位掩码对应关系(2的幂次方)
读书 = 1 (2⁰) → 二进制 00000001
游戏 = 2 (2¹) → 二进制 00000010
音乐 = 4 (2²) → 二进制 00000100
运动 = 8 (2³) → 二进制 00001000
旅游 = 16 (2⁴) → 二进制 00010000
美食 = 32 (2⁵) → 二进制 00100000
电影 = 64 (2⁶) → 二进制 01000000
购物 = 128 (2⁷) → 二进制 10000000
组合存储原理:
用户选择了"读书"和"音乐"
实际存储:1 | 4 = 5 → 二进制 00000101
显示为:'读书,音乐'
用户全选
实际存储:1|2|4|8|16|32|64|128 = 255 → 二进制 11111111
显示为:'读书,游戏,音乐,运动,旅游,美食,电影,购物'
2.SET的三种查询方式
(1)位运算查询(最高效)
sql
1. 查询包含"音乐"(4)的用户
SELECT * FROM player WHERE hobby & 4;
2. 查询同时包含"音乐"(4)和"运动"(8)的用户
SELECT * FROM player WHERE hobby & 12 = 12; -- 4+8=12
3. 查询只包含"音乐"和"运动"的用户(精确匹配)
SELECT * FROM player WHERE hobby = 12;
4. 查询不包含"游戏"(2)的用户
SELECT * FROM player WHERE NOT (hobby & 2);
(2)find_in_set(sub,str_list)查询
sub是字符串,在只知晓字符串的时候可以用这个查询。
sql
查询包含"音乐"的用户
SELECT * FROM player WHERE FIND_IN_SET('音乐', hobby);
查询包含"音乐"或"运动"的用户
SELECT * FROM player
WHERE FIND_IN_SET('音乐', hobby)
OR FIND_IN_SET('运动', hobby);
注意sub只能是字符串,不能用数字带替。
(3)LIKE模糊查询
sql
查询包含"音乐"的用户
SELECT * FROM player WHERE hobby LIKE '%音乐%';
查询以"音乐"开头的
SELECT * FROM player WHERE hobby LIKE '音乐%';
查询以"音乐"结尾的
SELECT * FROM player WHERE hobby LIKE '%音乐';
3.SET的增删改操作
(1)增加
sql
给id=1的用户添加"运动"(8)
UPDATE player
SET hobby = hobby | 8
WHERE id = 1;
(2)删除
sql
从id=1的用户移除"运动"(8)
UPDATE player
SET hobby = hobby & ~8
WHERE id = 1;
(3)切换选项(有则删,无则加)
类似于开关
sql
切换"运动"选项
UPDATE player
SET hobby = hobby ^ 8
WHERE id = 1;