数据类型
MySQL 数据类型详解
MySQL 支持多种数据类型,可分为数值、字符串、日期时间、枚举/集合以及 JSON 等。选择合适的类型可以优化存储空间和查询性能。
一、数值类型
| 类型 | 字节数 | 有符号范围 | 无符号范围 | 说明 |
|---|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 很小的整数(如性别、状态标志) |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 较小整数(如年龄、评分) |
| INT / INTEGER | 4 | -2^31 ~ 2^31-1(约 -21亿 ~ 21亿) | 0 ~ 2^32-1 | 常用整数(如 ID、数量) |
| BIGINT | 8 | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 | 极大整数(如大型系统主键、时间戳) |
| DECIMAL(M, D) | 变长 | 取决于 M, D | 取决于 M, D | 精确小数,用于金融、会计等需要精确保留的场景 |
| FLOAT | 4 | ±1.175E-38 ~ ±3.402E+38 | 同上 | 单精度浮点数,近似值 |
| DOUBLE | 8 | ±2.225E-308 ~ ±1.798E+308 | 同上 | 双精度浮点数,近似值(精度比 FLOAT 高) |
说明:
- DECIMAL(M, D):
M表示总位数(精度),D表示小数位数。例如DECIMAL(10, 2)可存储最大 99999999.99。 - 对于货币金额,永远不要使用 FLOAT/DOUBLE,因为存在精度丢失。应使用
DECIMAL或以“分”为单位存储整数。 - 使用
UNSIGNED属性可使字段只存储非负数,取值范围扩大一倍。
二、字符串类型
| 类型 | 最大长度 | 说明 |
|---|---|---|
| CHAR(N) | 0 ~ 255 字符 | 固定长度,不足部分用空格填充。适合长度固定的短字符串(如国家代码、MD5 哈希)。 |
| VARCHAR(N) | 0 ~ 65535 字符(实际受行大小限制) | 可变长度,额外使用 1~2 字节存储长度。适合长度可变的字符串(如用户名、标题)。 |
| TINYTEXT | 255 字符 | 短文本块 |
| TEXT | 65535 字符(约 64KB) | 较长的文本(如文章正文、评论) |
| MEDIUMTEXT | 16MB | 较长文本(如书籍章节目录) |
| LONGTEXT | 4GB | 极大文本 |
| BLOB | 65535 字节 | 二进制大对象(存储图片、文件等) |
| MEDIUMBLOB | 16MB | 较大二进制数据 |
| LONGBLOB | 4GB | 极大二进制数据 |
选择建议:
- 短字符串且长度接近固定 →
CHAR - 长度变化较大且不超过 255 字符 →
VARCHAR(但VARCHAR实际可更大,只是超过 255 需要额外考虑) - 较长的文字内容 →
TEXT系列 - 二进制文件(图片、音频等)一般不建议存储在数据库中,而是存储文件路径,或用专门的对象存储。但如果必须存,使用
BLOB。
注意:
TEXT与VARCHAR的区别:TEXT会单独存储,可能产生额外的行溢出,影响性能;索引时需指定前缀长度。
三、日期与时间类型
| 类型 | 格式 | 范围 | 说明 |
|---|---|---|---|
| DATE | 'YYYY-MM-DD' | '1000-01-01' ~ '9999-12-31' | 仅日期 |
| TIME | 'HH:MM:SS' 或 'HHH:MM:SS' | '-838:59:59' ~ '838:59:59' | 仅时间(可用于时间段) |
| DATETIME | 'YYYY-MM-DD HH:MM:SS' | '1000-01-01 00:00:00' ~ '9999-12-31 23:59:59' | 日期+时间(不受时区影响) |
| TIMESTAMP | 'YYYY-MM-DD HH:MM:SS' | '1970-01-01 00:00:01' UTC ~ '2038-01-19 03:14:07' UTC | 带时区的日期+时间,存储为 UTC 值,转换因时区设置而定 |
| YEAR | 'YYYY' | 1901 ~ 2155 | 仅年份 |
选择建议:
- 只需要日期 →
DATE - 只需要时间 →
TIME - 需要存储具体时刻且时区无关(如生日、历史事件) →
DATETIME - 需要自动更新为当前时间(如
ON UPDATE CURRENT_TIMESTAMP)或与时区联动 →TIMESTAMP(注意 2038 年问题) - 存储占用:MySQL 5.6.4 起,
TIMESTAMP占用 4 字节,DATETIME占用 5 字节(均为不含小数秒的部分,小数秒精度每级额外占 0~3 字节);5.6.4 之前DATETIME占用 8 字节。根据需求选择。
常用时间函数:
NOW() -- 当前日期时间
CURDATE() -- 当前日期
CURTIME() -- 当前时间
DATE_ADD() -- 日期加法
DATEDIFF() -- 日期差
四、其他类型
1. ENUM(枚举)
从预定义列表中选取一个值。存储时占用 1~2 字节,比 VARCHAR 更高效。
gender ENUM('male', 'female', 'other')
优点:数据紧凑、防止非法输入。缺点:修改枚举列表成本高,不灵活。适合状态固定且值很少的字段。
2. SET(集合)
从预定义列表中选取零个或多个值。每个值用一个位表示,最多 64 个选项。
interests SET('sports', 'music', 'reading', 'travel')
存储时按位存储,占用 1~8 字节。适合多选的固定选项,但业务变更时不如关联表灵活。
3. JSON(MySQL 5.7+)
原生支持 JSON 数据类型,可存储和查询 JSON 文档。
CREATE TABLE users (id INT, profile JSON);
INSERT INTO users VALUES (1, '{"name":"Alice", "age":30}');
SELECT profile->>'$.name' FROM users WHERE id = 1;
优点:灵活存储半结构化数据,支持索引(生成列)。缺点:查询性能不如规范化的列,适合不常变动结构的数据。
五、数据类型选择原则
- 尽量使用最小满足需求的类型:例如年龄用
TINYINT UNSIGNED(0~255)而非INT。 - 简单优先:能用
INT就不用VARCHAR存储数字,能用DATE就不用DATETIME。 - 精度敏感用
DECIMAL:金额、重量等必须精确的场景。 - 字符串长度固定用
CHAR:如 MD5 值(32 字符)、国家代码(2 字符)。 - 大文本走
TEXT或文件系统:避免在数据库中存储超大文本或二进制文件影响性能。 - 使用
ENUM/SET谨慎:列表变化频繁时不适用,可改用关联表或应用层校验。 - JSON 字段适合存储不常查询的内部结构:如果需要通过 JSON 内部字段过滤,建议创建生成列并建立索引。
六、总结表
| 分类 | 推荐类型 | 不推荐类型 |
|---|---|---|
| 整数 ID | INT / BIGINT | VARCHAR(除非有特殊业务需求) |
| 金额 | DECIMAL(10,2) | FLOAT / DOUBLE |
| 用户名 | VARCHAR(50) | CHAR(长字段会浪费空间) |
| 固定代码 | CHAR(2) | VARCHAR(稍浪费存储 + 长度字节) |
| 日期时间 | DATETIME 或 TIMESTAMP | VARCHAR(丧失日期函数便利性和索引效率) |
| 多选标志 | 位运算 INT 或关联表 | SET(扩展性差) |
| JSON 数据 | JSON 类型 | TEXT(失去 JSON 函数支持) |
正确选择数据类型,可以有效减少存储空间、提升查询性能,同时保证数据完整性。建议在表设计阶段仔细斟酌每个字段的类型和约束。
参考文献
| 资料 | 说明 |
|---|---|
| MySQL 8.0 手册 | 官方 |
| 数据存储导读 | 学习路径 |
相关文章
常用函数
MySQL 提供了丰富的内置函数,用于处理字符串、数值、日期和时间以及条件逻辑。下面分类介绍最常用的基础函数。
多表查询
多表查询用于从两个或更多表中获取数据。常见的连接类型包括内连接、外连接(左、右)和自连接。
MySQL 安装与基本操作
MySQL 的安装因操作系统而异,但安装完成后,通过命令行客户端连接并进行基本管理的方法是通用的。下面分别介绍安装方式和常用命令。
查询数据
数据查询语言(DQL)用于从数据库中检索数据,核心是 SELECT 语句。下面从基础查询、条件筛选、排序、限制行数、聚合与分组等方面进行介绍。
数据库与表的基本操作
DDL(Data Definition Language)用于定义数据库结构,包括创建、修改、删除数据库和表。下面介绍 MySQL 中常用的 DDL 语句。
数据操作
DML(Data Manipulation Language)用于对表中的数据进行增(INSERT)、删(DELETE)、改(UPDATE)。下面详细介绍这三类操作。
Series
mysql
11 / 11