MySQL数据类型定义了表中字段可以存储的数据格式和范围,合理选择数据类型不仅能节省存储空间,还能提升查询和写入的性能,是数据库设计环节中不可忽视的部分。
MySQL数据类型分类
数值类型
数值类型用于存储数字相关的数据,分为整数类型和小数类型,不同的子类型对应不同的存储范围和占用空间。
整数类型
常见的整数类型及特性如下:
| 类型名称 | 占用字节 | 有符号范围 | 无符号范围 | 适用场景 |
|---|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 存储状态值、小范围计数 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 存储中等范围的整数 |
| INT | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 | 常规整数存储,如用户ID |
| BIGINT | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 | 存储超大整数,如订单ID |
创建整数类型字段时可以指定UNSIGNED关键字表示无符号,指定ZEROFILL关键字会在数字不足位数时用0填充,示例代码如下:
-- 创建用户表,用户ID使用无符号INT,状态用TINYINT
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
status TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '用户状态 1正常 0禁用',
age TINYINT UNSIGNED ZEROFILL COMMENT '年龄,不足3位用0填充'
);
小数类型
小数类型分为浮点型和定点型,浮点型FLOAT和DOUBLE存在精度丢失问题,适合对精度要求不高的场景;定点型DECIMAL可以指定精度和小数位数,适合存储金额等需要精确计算的场景。
示例代码如下:
-- 创建订单表,金额使用DECIMAL类型保证精度
CREATE TABLE order_info (
order_id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
total_amount DECIMAL(10,2) NOT NULL COMMENT '订单总金额,最多10位,小数2位'
);
字符串类型
字符串类型用于存储文本数据,不同类型的存储方式和适用场景差异较大。
CHAR:定长字符串,长度范围0~255,适合存储长度固定的数据,比如手机号、身份证号,不足指定长度会用空格填充,查询效率比VARCHAR高。VARCHAR:变长字符串,长度范围0~65535,适合存储长度不固定的文本,比如用户昵称、地址,只会占用实际长度加1~2个字节的额外空间。TEXT:长文本类型,分为TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT,适合存储大段文本,比如文章正文、评论内容,不能设置默认值。BLOB:二进制大对象类型,用于存储图片、文件等二进制数据,实际开发中一般不会直接存在数据库,而是存文件路径。
示例代码如下:
-- 创建文章表,标题用VARCHAR,内容用TEXT
CREATE TABLE article (
article_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL COMMENT '文章标题',
content TEXT NOT NULL COMMENT '文章内容',
author_phone CHAR(11) NOT NULL COMMENT '作者手机号'
);
日期时间类型
日期时间类型用于存储时间相关的数据,常见类型如下:
DATE:存储日期,格式为YYYY-MM-DD,范围1000-01-01到9999-12-31。TIME:存储时间,格式为HH: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:存储时间戳,范围1970-01-01 00:00:00到2038-01-19 03:14:07,和时区相关,插入和更新时会自动转换为当前时区的时间。YEAR:存储年份,格式为YYYY,范围1901到2155。
示例代码如下:
-- 创建日志表,记录创建时间和更新时间
CREATE TABLE operate_log (
log_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
);
数据类型选择技巧
在实际业务中选择数据类型可以遵循以下原则:
- 优先选择占用空间小的类型,比如能用
TINYINT就不要用INT,节省存储空间。 - 优先选择简单类型,比如存储日期用
DATETIME而不是用VARCHAR存储日期字符串,便于时间相关的查询和计算。 - 尽量避免NULL值,字段尽量设置为
NOT NULL,可以设置默认值,NULL值会占用额外的存储空间,也会影响查询性能。 - 金额类数据必须用
DECIMAL类型,不要用FLOAT或DOUBLE,避免精度丢失导致金额计算错误。 - 固定长度的字符串用
CHAR,变长字符串用VARCHAR,大段文本用TEXT。
常见问题说明
很多开发者会疑惑DATETIME和TIMESTAMP的区别,除了范围和时区特性之外,TIMESTAMP在插入和更新时如果不指定值会自动设置为当前时间,而DATETIME需要手动设置默认值。另外VARCHAR的长度指的是字符数而不是字节数,如果是utf8mb4编码,一个字符最多占4个字节,所以定义VARCHAR(255)最多可能占用255*4+2=1022个字节,仍然在行存储的限制范围内。
注意:MySQL中每个行的总存储长度不能超过65535字节,所以使用VARCHAR时需要结合字符集计算实际占用的空间,避免超过行长度限制。