MySQL 数据库(二):数据类型

数据类型是数据库表设计的基石,选择正确的数据类型直接影响存储空间、查询性能和数据完整性

一、数值类型

1. 整数类型

类型 字节 有符号范围 无符号范围 说明
TINYINT 1 -128 ~ 127 0 ~ 255 状态、标志位
SMALLINT 2 -32768 ~ 32767 0 ~ 65535 小范围数值
MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 16777215 中等范围
INT 4 -21亿 ~ 21亿 0 ~ 42亿 通用整数
BIGINT 8 -922亿亿 ~ 922亿亿 0 ~ 1844亿亿 大数值(如时间戳、ID)
使用建议
复制代码
-- 状态字段:TINYINT
status TINYINT DEFAULT 1 COMMENT '状态:0-禁用 1-正常'

-- 年龄:TINYINT UNSIGNED
age TINYINT UNSIGNED DEFAULT 0

-- 普通ID:INT UNSIGNED
id INT UNSIGNED AUTO_INCREMENT

-- 大数据量:BIGINT UNSIGNED
user_id BIGINT UNSIGNED NOT NULL

二、小数类型

1. 浮点数(FLOAT / DOUBLE)

复制代码
-- 近似值,会有精度误差
FLOAT          -- 4字节,单精度
DOUBLE         -- 8字节,双精度

-- 浮点数不精确
SELECT 0.1 + 0.2;  -- 0.30000000000000004(可能有误差)

2. 定点数(DECIMAL)

复制代码
DECIMAL(M, D)   -- M:总位数,D:小数位数
DECIMAL(10, 2)  -- 总共10位,其中2位小数,范围 -99999999.99 ~ 99999999.99
使用建议
复制代码
-- 金额必须用 DECIMAL
price DECIMAL(10, 2) NOT NULL DEFAULT 0.00

-- 不要用 FLOAT 存钱
price FLOAT  -- 会丢失精度

-- 不要用 DOUBLE 存钱
price DOUBLE -- 同样有精度问题

三、字符串类型

1. 定长字符串(CHAR)

复制代码
CHAR(N)  -- N:0~255 个字符
  • 固定长度,不够用空格填充

  • 适合长度固定的字段

    -- 适合用 CHAR
    gender CHAR(1) -- 'M' / 'F'
    status CHAR(1) -- '0' / '1'
    id_card CHAR(18) -- 身份证号

2. 变长字符串(VARCHAR)

复制代码
VARCHAR(N)  -- N:0~65535 个字符
  • 可变长度,只占用实际长度 + 1/2 字节

  • 适合长度不固定的字段

    -- 适合用 VARCHAR
    username VARCHAR(50)
    email VARCHAR(100)
    address VARCHAR(255)

CHAR vs VARCHAR 选择
场景 推荐 原因
长度固定 CHAR 效率更高
长度变化大 VARCHAR 节省空间
长度 > 255 VARCHAR / TEXT CHAR 不支持 > 255
频繁更新 CHAR 定长不会引起页分裂
复制代码
-- 示例:性别用 CHAR,用户名用 VARCHAR
CREATE TABLE users (
    gender CHAR(1) NOT NULL,
    username VARCHAR(50) NOT NULL
);

3. 大文本(TEXT)

类型 最大长度 说明
TINYTEXT 255 极少使用
TEXT 65535 (约64KB) 常用
MEDIUMTEXT 1677万 (约16MB) 大文本
LONGTEXT 42亿 (约4GB) 超大文本
注意
  • TEXT 不能有默认值

  • TEXT 查询时可能产生临时表,影响性能

  • 尽量用 VARCHAR 替代 TEXT

    -- 错误:TEXT 不能设置默认值
    content TEXT DEFAULT '' -- 报错

    -- 正确
    content TEXT

四、二进制类型

类型 最大长度 说明
BINARY 255 定长二进制
VARBINARY 65535 变长二进制
BLOB 65535 二进制大对象
MEDIUMBLOB 1677万 中等二进制
LONGBLOB 42亿 超大二进制
复制代码
-- 存储图片、文件等
avatar MEDIUMBLOB

五、日期时间类型

类型 格式 范围 说明
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 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 Unix 时间戳
YEAR YYYY 1901 ~ 2155 年份

TIMESTAMP vs DATETIME

对比 TIMESTAMP DATETIME
存储空间 4字节 8字节
范围 1970-2038 1000-9999
时区影响 自动转换 不转换
自动更新 支持 不支持
使用建议
复制代码
-- 创建时间:用 DATETIME 或 TIMESTAMP
created_at DATETIME DEFAULT CURRENT_TIMESTAMP

-- 更新时间:用 TIMESTAMP(支持自动更新)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

-- 只需要日期:用 DATE
birthday DATE

-- 2038年问题:TIMESTAMP 在 2038 年溢出
expire_time TIMESTAMP  -- 2038-01-19 之后会出问题
expire_time DATETIME   -- 无此问题

六、JSON 类型(MySQL 5.7+)

复制代码
-- 创建 JSON 列
CREATE TABLE products (
    id INT PRIMARY KEY,
    attributes JSON
);

-- 插入 JSON 数据
INSERT INTO products VALUES (1, '{"color": "red", "size": "L"}');

-- 查询 JSON 字段
SELECT JSON_EXTRACT(attributes, '$.color') FROM products;  -- "red"
SELECT attributes->>'$.color' FROM products;               -- red

-- JSON 函数
SELECT JSON_KEYS(attributes) FROM products;                -- ["color", "size"]

说明:

  1. 整数类型选最小够用的TINYINTSMALLINTINTBIGINT

  2. 金额必须用 DECIMAL,不能用浮点数

  3. 定长用 CHAR,变长用 VARCHAR

  4. 时间推荐 DATETIMETIMESTAMP 有 2038 年问题

  5. 大文本用 TEXT ,但尽量用 VARCHAR 替代

  6. JSON 类型适合灵活、非结构化的数据

相关推荐
野生技术架构师1 小时前
Redis 和 MySQL 如何保证数据一致性?先更新数据库还是先删缓存,延迟双删、MQ、Canal 一次讲透
数据库·redis·缓存
鸽芷咕1 小时前
SQL Server数据迁移到金仓数据库复盘:从怕性能翻车,到TPS提升60%
数据库
jason.zeng@15022072 小时前
服务器磁盘读写效率,网络吞吐量查看,mysql性能调优
服务器·网络·mysql
HAYDENR2 小时前
数据库如何做性能优化?数据库性能调优有哪些常见注意事项?
数据库·性能优化
Light Gao2 小时前
企业级灰度发布技术方案
网络·数据库·oracle
一水2 小时前
AI 时代审查思维:审查第一篇
java·jvm·数据库·spring
赵广陆2 小时前
企业实战:Milvues向量数据库实践
数据库·pycharm·langchain
微学AI3 小时前
把时间序列真正用起来:TimechoAI 使用与时序分析实战
数据库·人工智能·大模型
cspttty3 小时前
管理类专业证书含金量排名
数据库