目录
[1. 整型类型](#1. 整型类型)
[2. 创建整型列](#2. 创建整型列)
[3. 数值范围与约束](#3. 数值范围与约束)
[4. BIT 位类型](#4. BIT 位类型)
[1. FLOAT 创建与范围](#1. FLOAT 创建与范围)
[2. 插入行为](#2. 插入行为)
[3. 精度问题](#3. 精度问题)
[4. DECIMAL(精确小数)](#4. DECIMAL(精确小数))
[1. CHAR(定长字符串)](#1. CHAR(定长字符串))
[2. VARCHAR(变长字符串)](#2. VARCHAR(变长字符串))
[3. CHAR 与 VARCHAR 的区别](#3. CHAR 与 VARCHAR 的区别)
[1. 创建枚举和集合列](#1. 创建枚举和集合列)
[2. ENUM 和 SET 的区别](#2. ENUM 和 SET 的区别)
[3. 数字插入](#3. 数字插入)
[4. 条件查找](#4. 条件查找)
一、整型
1. 整型类型
| 类型 | 字节数 |
|---|---|
| TINYINT | 1 |
| SMALLINT | 2 |
| MEDIUMINT | 3 |
| INT | 4 |
| BIGINT | 8 |
2. 创建整型列
-- 有符号整型
CREATE TABLE t1 (num TINYINT);
-- 无符号整型(正数范围更大)
CREATE TABLE t2 (num TINYINT UNSIGNED);
注意:创建列时,先写列名,再写类型。
3. 数值范围与约束
1 字节有符号整数的表示范围是 -128 ~ 127。
MySQL 与 C 不同:插入越界的值会直接报错,而不是截断或溢出。
INSERT INTO t1 VALUES(-128); -- 成功
INSERT INTO t1 VALUES(-129); -- 报错

这种越界报错机制是一种约束,用于规范用户的行为,保证数据的合法性。
4. BIT 位类型
-- 创建一个 BIT(1) 列,表示 1 位的二进制值
CREATE TABLE t3 (id INT, online BIT(1));
括号内的数字表示 BIT 的位数,最大支持 64 位。
在老版本 MySQL 中,BIT 类型可能默认用 ASCII 码显示(显示为空白或乱码),但新版本可以直接显示数字。
-- 查看数据(十六进制显示)
SELECT id, HEX(online) FROM t3;

二、浮点类型
1. FLOAT 创建与范围
-- 共 4 位数字,其中 2 位是小数
CREATE TABLE t4 (f FLOAT(4,2));
由于指定了 (4,2),该列的取值范围是 -99.99 ~ 99.99。
2. 插入行为
-
插入
10.1→ 存储为10.10(补零) -
插入
10.101→ 四舍五入为10.10 -
插入
99.995→ 四舍五入为100.00,超出范围,报错
注意:浮点数插入时比整型宽容,不会因为四舍五入而报错,只有四舍五入后仍超出范围才报错。

3. 精度问题
-- 移除浮点数的精度限制
ALTER TABLE t4 MODIFY f FLOAT;
移除精度限制后,插入一个较大的数:
INSERT INTO t4 VALUES(1422692838.2984982);

可以看到,FLOAT 会丢失小数部分的精度。
4. DECIMAL(精确小数)
DECIMAL 可以精确表示小数,不会出现精度丢失。
CREATE TABLE t5 (
f1 FLOAT(10,8),
f2 DECIMAL(10,8)
);
INSERT INTO t5 VALUES(10.10341345, 10.10341345);

-
FLOAT:有误差
-
DECIMAL:可以精确表示
DECIMAL 的能力:
-
最多可存储 65 位数字
-
小数部分最多 30 位
-
默认值为
(10,0)
三、字符串类型
1. CHAR(定长字符串)
最大长度为 255 个字符。
-- 创建一个长度为 2 的字符串列
CREATE TABLE t6 (name CHAR(2));
注意 :这里的 2 是字符数,而不是字节数。
INSERT INTO t6 VALUES('ab'); -- 2 个英文字符
INSERT INTO t6 VALUES('一'); -- 1 个中文字符(UTF-8 占 3 字节,但算 1 个字符)
INSERT INTO t6 VALUES('一a'); -- 1 个中文 + 1 个英文
INSERT INTO t6 VALUES('一二'); -- 2 个中文字符
在 UTF-8 编码下,一个汉字占 3 个字节,但在 MySQL 中仍算作1 个字符。
2. VARCHAR(变长字符串)
最大长度为 65535 个字符(实际受行大小限制)。
CREATE TABLE t8 (name VARCHAR(3));
注意:不能直接创建 65535 长度的 VARCHAR 列:
CREATE TABLE t9 (name VARCHAR(65535));
-- ERROR 1074: Column length too big for column 'name' (max = 16383); use BLOB or TEXT instead
错误信息显示最大长度为 16383,这是因为:
-
UTF-8 中一个字符最多占 3 个字节
-
VARCHAR 还需要额外 1-2 字节记录长度
-
65535 / 3 ≈ 21845,但还要减去长度记录的空间
实际上,16383 是经过计算后的安全上限。
-- 可以创建 16382 长度的 VARCHAR
CREATE TABLE t10 (name VARCHAR(16382));
3. CHAR 与 VARCHAR 的区别
| 特性 | CHAR | VARCHAR |
|---|---|---|
| 存储方式 | 定长 | 变长 |
| 空间效率 | 固定分配,可能浪费 | 按需分配,节省空间 |
| 速度 | 稍快 | 稍慢 |
| 最大长度 | 255 字符 | 65535 字符(受实际限制) |
四、日期时间类型
| 类型 | 格式 | 字节数 | 说明 |
|---|---|---|---|
| DATE | YYYY-MM-DD |
3 | 年月日 |
| TIME | HH:MM:SS |
3 | 时分秒 |
| DATETIME | YYYY-MM-DD HH:MM:SS |
8 | 年月日时分秒 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS |
4 | 时间戳(从 1970-01-01 开始的秒数) |
| YEAR | YYYY |
1 | 年份 |
CREATE TABLE t11 (
t1 DATE,
t2 DATETIME,
t3 TIMESTAMP
);
INSERT INTO t11 VALUES('2026-3-28', '2026-3-28 20:48:01', NOW());
说明:
-
老版本 MySQL 中,TIMESTAMP 列会自动填充当前时间戳
-
新版本需要显式传入
NOW()或CURRENT_TIMESTAMP
五、枚举与集合
1. 创建枚举和集合列
CREATE TABLE t12 (
name VARCHAR(20),
gender ENUM('男', '女'),
hobby SET('唱', '跳', 'rap', '篮球')
);
2. ENUM 和 SET 的区别
| 特性 | ENUM(枚举) | SET(集合) |
|---|---|---|
| 多选 | 只能选一个值 | 可以选多个值 |
| 存储方式 | 存储索引(1,2,3...) | 存储位图(每个选项占 1 位) |
| 插入示例 | '男' |
'唱,跳' |
-- ENUM:只能选一个
INSERT INTO t12 VALUES('甲', '男', '唱');
-- SET:可以选多个,用逗号分隔
INSERT INTO t12 VALUES('乙', '男', '唱,跳');
3. 数字插入
ENUM 和 SET 都支持用数字插入,数字对应选项的索引(从 1 开始)。
INSERT INTO t12 VALUES('丙', '1', '3');
-
gender = '1':表示 ENUM 的第一个选项('男') -
hobby = '3':3 的二进制是11,表示选中第 1 位和第 2 位('唱' 和 '跳')

4. 条件查找
-- 查找性别为男(ENUM 值为 1)
SELECT * FROM t12 WHERE gender = 1;
-- 查找兴趣同时包含 '唱' 和 '跳' 的人
SELECT * FROM t12
WHERE FIND_IN_SET('唱', hobby) AND FIND_IN_SET('跳', hobby);
FIND_IN_SET(str, set) 函数:返回 str 在 set 中的位置,如果不存在则返回 0。