MySQL_数据类型知识

MySQL 数据类型

一、核心目标

  • 理解数据库中"实体、表、记录、字段、属性"之间的对应关系。
  • 掌握 MySQL 常用数据类型的分类。
  • 能根据数据的取值范围、长度、精度和使用场景选择合适的数据类型。
  • 重点掌握 CHARVARCHARTEXT 之间的区别,以及常见日期时间类型的使用。

二、基础概念

在面向对象设计与数据库设计中,可以建立如下对应关系:

面向对象概念 数据库概念
实体 / 表
对象实例 一条记录 / 数据行
属性 字段 / 列
属性值 字段中保存的数据

定义表字段时,通常需要确定三件事:

  1. 字段名称;
  2. 字段的数据类型;
  3. 字段的长度、精度或其他约束。

MySQL 常用数据类型可分为四类:

  • 数值类型
  • 字符串类型
  • 二进制类型
  • 日期时间类型

三、数值类型

3.1 整数类型

类型 存储空间 有符号范围 无符号范围
TINYINT 1 字节 -128 ~ 127 0 ~ 255
SMALLINT 2 字节 -32768 ~ 32767 0 ~ 65535
MEDIUMINT 3 字节 -8388608 ~ 8388607 0 ~ 16777215
INT / INTEGER 4 字节 -2147483648 ~ 2147483647 0 ~ 4294967295
BIGINT 8 字节 -2^632^63-1 0 ~ 2^64-1

记忆规律

整数类型每增加 1 个字节,能够表示的二进制位数就增加 8 位。

对于占用 n 位的整数:

  • 有符号范围:-2^(n-1)2^(n-1)-1
  • 无符号范围:02^n-1

使用建议

  • 年龄、状态值:可考虑 TINYINT
  • 数量较小的编号:可考虑 SMALLINT
  • 常规主键、数量、计数:常用 INT
  • 数据量极大的主键、流水号:可考虑 BIGINT
  • 字段不需要负数时,可以使用 UNSIGNED

示例:

sql 复制代码
CREATE TABLE product (
    id BIGINT UNSIGNED PRIMARY KEY,
    stock INT UNSIGNED,
    status TINYINT
);

3.2 位类型与布尔类型

BIT[(M)]

  • 位值类型。
  • M 表示每个值占用的位数。
  • M 的范围为 1~64。
  • 省略 M 时,默认长度为 1 位。

示例:

sql 复制代码
is_enabled BIT(1)

BOOL

  • BOOLTINYINT(1) 的同义写法。
  • 0 通常表示假。
  • 0 值通常表示真。

示例:

sql 复制代码
is_deleted BOOL DEFAULT FALSE

3.3 浮点数与定点数

类型 存储空间 特点
FLOAT[(M,D)] 4 字节 单精度浮点数,约可保证 7 位十进制有效精度
DOUBLE[(M,D)] 8 字节 双精度浮点数,约可保证 15 位十进制有效精度
DECIMAL[(M,D)] 动态 定点数,适合要求精确计算的数据

其中:

  • M:总位数
  • D:小数位数
  • DECIMALM 最大为 65
  • DECIMALD 最大为 30
  • 省略 M 时,默认值为 10
  • 省略 D 时,默认值为 0
  • M 不计算小数点和负号

示例:

sql 复制代码
price DECIMAL(10, 2)

该字段最多保存 10 位数字,其中小数部分占 2 位,例如:

text 复制代码
12345678.90

选择原则

  • 科学计算、允许近似误差:FLOATDOUBLE
  • 金额、财务、精确比例:优先使用 DECIMAL
  • 不应使用浮点数直接保存要求绝对精确的金额

四、字符串与二进制类型

4.1 常见字符串类型

类型 特点 最大长度
CHAR[(M)] 固定长度字符串 255 个字符
VARCHAR(M) 可变长度字符串 最大受行大小和字符集影响,声明上限可到 65535
TINYTEXT 小文本 255 字节
TEXT 文本 65535 字节
MEDIUMTEXT 中文本 16777215 字节
LONGTEXT 大文本 4294967295 字节

注意:

  • CHARVARCHAR 的长度通常以字符为单位。
  • TEXT 系列的容量以字节为单位。
  • 实际可保存的字符数会受到字符集影响。
  • 使用多字节字符集时,一个字符可能占用多个字节。

4.2 常见二进制类型

类型 特点 最大长度
BINARY[(M)] 固定长度二进制数据 255 字节
VARBINARY(M) 可变长度二进制数据 M 指定
TINYBLOB 小型二进制数据 255 字节
BLOB 二进制数据 65535 字节
MEDIUMBLOB 中型二进制数据 16777215 字节
LONGBLOB 大型二进制数据 4294967295 字节

字符串类型与二进制类型的区别

  • 字符串类型保存字符,通常受字符集和排序规则影响。
  • 二进制类型保存原始字节,比较时更关注每个字节的数值。
  • 文本数据适合使用 CHARVARCHARTEXT
  • 文件内容、哈希字节、加密结果等原始数据可考虑二进制类型。

4.3 ENUMSET

ENUM

sql 复制代码
ENUM('待支付', '已支付', '已取消')

特点:

  • 从预定义列表中选择一个值。
  • 还可能保存空字符串或 NULL,具体取决于字段约束和 SQL 模式。
  • 最多可定义 65535 个不同元素。
  • 内部通常使用整数表示。

适用场景:

  • 状态值固定且变化较少。
  • 每条记录只能选择一个状态。

SET

sql 复制代码
SET('读', '写', '删除')

特点:

  • 可以从预定义列表中选择零个、一个或多个值。
  • 最多可定义 64 个元素。
  • 内部通常使用整数位组合表示。

适用场景:

  • 一条记录允许同时具备多个固定选项。

对比

对比项 ENUM SET
可选数量 只能选一个 可以选多个
最大元素数 65535 64
典型场景 单一状态 多个标签或权限

五、字符集与排序规则

字符串列可以指定字符集和排序规则。

示例:

sql 复制代码
name VARCHAR(50)
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_0900_ai_ci

排序规则影响:

  • 字符串比较
  • 大小写是否敏感
  • 重音符号是否敏感
  • 排序顺序

二进制风格的排序规则通常以 _bin 结尾,例如:

sql 复制代码
utf8mb4_bin

这种排序规则更接近按照字符编码值进行比较,常用于要求严格区分大小写或字符差异的场景。


六、CHARVARCHAR

6.1 核心区别

对比项 CHAR(M) VARCHAR(M)
长度 固定长度 可变长度
M 的含义 固定字符长度 最大字符长度
最大声明长度 255 个字符 受行大小和字符集限制
存储方式 不足时按固定长度处理 按实际数据长度存储
长度记录 通常不需要额外记录实际长度 需要额外 1 或 2 字节记录长度
尾部空格 读取时通常会去除尾部填充空格 通常保留未被截断的尾部空格
空间利用率 较低 较高
典型性能特点 定长数据处理较直接 更节省空间

6.2 存储示例

sql 复制代码
CREATE TABLE vc (
    v VARCHAR(4),
    c CHAR(4)
);

INSERT INTO vc VALUES ('ab ', 'ab ');

SELECT
    CONCAT('(', v, ')'),
    CONCAT('(', c, ')')
FROM vc;

可能看到的结果:

text 复制代码
(ab )
(ab)

含义:

  • VARCHAR 中原有的尾部空格仍然可见。
  • CHAR 读取时会去掉用于填充的尾部空格。

6.3 选择原则

适合 CHAR 的数据:

  • 长度基本固定的数据
  • 身份证号
  • 学号
  • 邮编
  • 固定长度摘要值,如 MD5 字符串
  • 固定格式的业务编码

适合 VARCHAR 的数据:

  • 姓名
  • 地址
  • 邮箱
  • 用户名
  • 标题
  • 长度变化明显的普通字符串

一句话记忆:

长度固定选 CHAR,长度变化选 VARCHAR


七、VARCHARTEXT

7.1 主要区别

对比项 VARCHAR TEXT
适合的数据长度 较短或中等长度 较长文本
最大容量 受单行总大小、字符集等限制 TEXT 最大 65535 字节
索引 更适合建立普通索引 常使用前缀索引或全文索引
查询场景 经常作为检索条件 通常保存正文、描述等内容
典型性能 短文本检索通常更方便 大文本处理成本通常更高

7.2 选择原则

选择 VARCHAR

  • 数据长度较小或中等。
  • 经常作为查询条件。
  • 需要建立普通索引。
  • 例如用户名、邮箱、标题、手机号。

选择 TEXT

  • 数据内容较长。
  • 不经常作为精确检索条件。
  • 例如文章正文、长备注、详细说明。

示例:

sql 复制代码
CREATE TABLE article (
    id BIGINT UNSIGNED PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    summary VARCHAR(1000),
    content LONGTEXT
);

八、日期时间类型

8.1 类型对比

类型 存储空间 主要用途 常见格式
TIMESTAMP[(fsp)] 4 字节 时间戳、记录创建或更新时间 YYYY-MM-DD hh:mm:ss[.fraction]
DATETIME[(fsp)] 8 字节 日期和时间的组合 YYYY-MM-DD hh:mm:ss[.fraction]
DATE 3 字节 只保存日期 YYYY-MM-DD
TIME[(fsp)] 3 字节 时间或持续时长 hh:mm:ss[.fraction]
YEAR[(4)] 1 字节 四位年份 YYYY

8.2 常见范围

类型 支持范围
TIMESTAMP 约从 1970-01-01 到 2038-01-19
DATETIME 1000-01-01 00:00:00 到 9999-12-31 23:59:59
DATE 1000-01-01 到 9999-12-31
TIME -838:59:59 到 838:59:59
YEAR 1901 到 2155

8.3 fsp:小数秒精度

fsp 用于指定秒的小数部分精度:

  • 范围:0~6
  • 0:没有小数秒
  • 3:精确到毫秒
  • 6:精确到微秒
  • 省略时默认精度为 0

示例:

sql 复制代码
created_at DATETIME(6)

可能保存:

text 复制代码
2026-07-20 15:30:45.123456

8.4 获取当前日期和时间

写法 同义函数 作用
CURRENT_DATE / CURRENT_DATE() CURDATE() 获取当前日期
CURRENT_TIME / CURRENT_TIME(fsp) CURTIME() 获取当前时间
CURRENT_TIMESTAMP / CURRENT_TIMESTAMP(fsp) NOW() 获取当前日期和时间

示例:

sql 复制代码
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
SELECT CURRENT_TIMESTAMP;
SELECT NOW();

8.5 日期类型选择

  • 只保存生日、入职日期:DATE
  • 保存完整业务时间:DATETIME
  • 保存记录创建或修改时间:常用 TIMESTAMPDATETIME
  • 保存时长、时间间隔:TIME
  • 只保存年份:YEAR

示例:

sql 复制代码
CREATE TABLE employee (
    id BIGINT UNSIGNED PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    birthday DATE,
    work_start_time TIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

九、数据类型选择总原则

9.1 范围够用即可

在能够覆盖业务范围的前提下,优先选择占用空间较小的类型。

例如:

  • 年龄不需要使用 BIGINT
  • 普通商品库存通常不需要使用 DECIMAL
  • 超大规模主键不宜使用 TINYINT

9.2 精确数据使用定点数

  • 金额、税率、结算数据:DECIMAL
  • 允许近似误差的计算:FLOATDOUBLE

9.3 长度固定与否决定字符串类型

  • 固定长度:CHAR
  • 长度变化:VARCHAR
  • 大段文字:TEXTMEDIUMTEXTLONGTEXT

9.4 是否需要检索决定文本方案

  • 经常按该字段查询、排序或建立索引:优先考虑 VARCHAR
  • 主要用于展示的大段内容:考虑 TEXT 系列

9.5 日期不要随意用字符串保存

不推荐:

sql 复制代码
birthday VARCHAR(20)

推荐:

sql 复制代码
birthday DATE

使用专用日期类型可以获得:

  • 合法性检查
  • 日期计算
  • 排序与比较
  • 日期函数支持

十、综合建表示例

sql 复制代码
CREATE TABLE user_profile (
    id BIGINT UNSIGNED PRIMARY KEY,
    student_no CHAR(12) NOT NULL,
    username VARCHAR(50) NOT NULL,
    gender ENUM('男', '女', '未知') DEFAULT '未知',
    age TINYINT UNSIGNED,
    balance DECIMAL(12, 2) DEFAULT 0.00,
    email VARCHAR(100),
    biography TEXT,
    avatar_data BLOB,
    birthday DATE,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
        ON UPDATE CURRENT_TIMESTAMP
);

字段分析:

字段 类型选择理由
id 数据量可能较大,使用无符号 BIGINT
student_no 长度固定,使用 CHAR
username 长度可变,使用 VARCHAR
gender 候选值固定且只能选一个,使用 ENUM
age 非负且范围小,使用 TINYINT UNSIGNED
balance 金额要求精确,使用 DECIMAL
biography 内容可能较长,使用 TEXT
avatar_data 保存二进制数据,使用 BLOB
birthday 只需要日期,使用 DATE
created_at 保存完整日期和时间,使用 DATETIME

十一、高频知识点

  1. INTINTEGER 是同义类型。
  2. BOOL 通常等价于 TINYINT(1)
  3. 有符号整数可以保存负数,无符号整数从 0 开始。
  4. FLOATDOUBLE 可能存在精度误差。
  5. 金额通常使用 DECIMAL
  6. CHAR 是定长字符串,VARCHAR 是变长字符串。
  7. CHAR 更适合固定长度数据,VARCHAR 更适合长度变化的数据。
  8. TEXT 适合大段文字,BLOB 适合二进制数据。
  9. ENUM 只能选择一个值,SET 可以选择多个值。
  10. DATE 只保存日期,DATETIME 保存日期和时间。
  11. TIME 的取值范围可以超过一天,因此也可用于表示较长时长。
  12. fsp 的范围为 0~6,用于控制小数秒精度。
  13. CURRENT_DATE 获取当前日期。
  14. CURRENT_TIME 获取当前时间。
  15. CURRENT_TIMESTAMPNOW() 获取当前日期和时间。

十二、易错点

易错点 1:把 VARCHAR(M)M 当作字节数

VARCHAR(M) 中的 M 通常表示最大字符数,但实际存储空间还会受到字符集影响。

易错点 2:用 FLOAT 保存金额

浮点数可能产生精度误差,金额应优先使用 DECIMAL

易错点 3:固定长度字段一律使用 VARCHAR

长度固定的数据使用 CHAR 通常更直观,例如学号、邮编和固定格式编码。

易错点 4:大段正文使用过短的 VARCHAR

文章正文、长说明等内容应考虑 TEXTMEDIUMTEXTLONGTEXT

易错点 5:日期保存成普通字符串

使用 DATEDATETIME 等专用类型,才能方便地进行日期比较、排序和计算。

易错点 6:混淆 ENUMSET

  • ENUM:单选
  • SET:多选

十三、知识速记

text 复制代码
整数:TINYINT < SMALLINT < MEDIUMINT < INT < BIGINT

近似小数:FLOAT、DOUBLE
精确小数:DECIMAL

固定字符串:CHAR
可变字符串:VARCHAR
大文本:TEXT / MEDIUMTEXT / LONGTEXT

固定二进制:BINARY
可变二进制:VARBINARY
大二进制:BLOB / MEDIUMBLOB / LONGBLOB

单选:ENUM
多选:SET

日期:DATE
日期时间:DATETIME
时间戳:TIMESTAMP
时间或时长:TIME
年份:YEAR

当前日期:CURRENT_DATE / CURDATE()
当前时间:CURRENT_TIME / CURTIME()
当前日期时间:CURRENT_TIMESTAMP / NOW()
相关推荐
姜太小白41 分钟前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
窝子面1 小时前
手搓最简前后端协作-node
javascript·数据库
吳所畏惧1 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈1 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HPFBoy2 小时前
log4net 数据库存日志正确配置
数据库
liuxiaowei32 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
破碎的南瓜2 小时前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
吠品4 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
SelectDB4 小时前
Apache Doris Variant 动态 JSON 实战教程:从建表到跑通 100M Agent 日志查询
数据库