MySQL数据类型

学习MySQL支持的各种数据类型及其用法

MySQL数据类型概述

MySQL支持多种数据类型,主要包括数值类型、日期和时间类型、字符串类型等。正确选择数据类型对数据库性能和存储效率至关重要。

数值类型

数值类型用于存储数字数据,包括整数类型和浮点数类型。

整数类型

类型 字节 有符号范围 无符号范围 描述
TINYINT 1 -128 到 127 0 到 255 非常小的整数
SMALLINT 2 -32,768 到 32,767 0 到 65,535 小整数
MEDIUMINT 3 -8,388,608 到 8,388,607 0 到 16,777,215 中等整数
INT/INTEGER 4 -2,147,483,648 到 2,147,483,647 0 到 4,294,967,295 标准整数
BIGINT 8 -2^63 到 2^63-1 0 到 2^64-1 大整数
整数类型使用示例
CREATE TABLE integer_example (
    id INT AUTO_INCREMENT PRIMARY KEY,
    age TINYINT UNSIGNED,
    score SMALLINT,
    population INT UNSIGNED,
    big_number BIGINT
);

浮点数类型

类型 字节 描述 精度
FLOAT 4 单精度浮点数 约7位小数
DOUBLE 8 双精度浮点数 约15位小数
DECIMAL(M,D) 变长 精确小数 M位总数,D位小数
浮点数类型使用示例
CREATE TABLE float_example (
    id INT,
    price DECIMAL(10, 2),    -- 总10位,2位小数
    percentage FLOAT,
    scientific_value DOUBLE
);
注意:对于需要精确计算的金额等数据,应使用DECIMAL类型而不是FLOAT或DOUBLE,以避免浮点数精度问题。

整数类型存储需求详解

类型存储字节最大值(有符号)最大值(无符号)
TINYINT1127255
SMALLINT232,76765,535
MEDIUMINT38,388,60716,777,215
INT42,147,483,6474,294,967,295
BIGINT89,223,372,036,854,775,80718,446,744,073,709,551,615

日期和时间类型

MySQL提供了多种日期和时间类型来存储时间数据。

类型 格式 范围 描述
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 时间戳,自动更新
YEAR YYYY 1901 到 2155 年份值

时区注意事项

TIMESTAMP类型存储的是UTC时间,检索时会根据当前时区转换;DATETIME则不做时区转换。

时区设置示例
-- 查看当前时区
SELECT @@global.time_zone, @@session.time_zone;

-- 设置会话时区
SET time_zone = '+08:00';
SET time_zone = 'Asia/Shanghai';

-- 转换时区
SELECT CONVERT_TZ('2023-01-01 12:00:00', '+00:00', '+08:00');
日期时间类型使用示例
CREATE TABLE datetime_example (
    id INT,
    birth_date DATE,
    meeting_time TIME,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    birth_year YEAR
);

字符串类型

字符串类型用于存储文本数据,包括定长和变长字符串。

文本字符串类型

类型 最大长度 描述 存储特点
CHAR(n) 255字符 定长字符串 固定长度,不足补空格
VARCHAR(n) 65,535字符 变长字符串 按实际长度存储
TINYTEXT 255字符 短文本字符串 变长存储
TEXT 65,535字符 文本字符串 变长存储
MEDIUMTEXT 16,777,215字符 中等长度文本 变长存储
LONGTEXT 4,294,967,295字符 长文本 变长存储
字符串类型使用示例
CREATE TABLE string_example (
    id INT,
    country_code CHAR(2),        -- 固定2字符,如'CN'
    username VARCHAR(50),       -- 最多50字符
    email VARCHAR(100),
    description TEXT,           -- 长文本描述
    long_content LONGTEXT      -- 超长文本内容
);
选择建议:对于固定长度的数据(如国家代码、性别代码)使用CHAR,对于变长数据使用VARCHAR,对于大段文本使用TEXT类型。

二进制字符串类型

类型 最大长度 描述
BINARY(n) 255字节 定长二进制字符串
VARBINARY(n) 65,535字节 变长二进制字符串
TINYBLOB 255字节 短二进制大对象
BLOB 65,535字节 二进制大对象
MEDIUMBLOB 16,777,215字节 中等二进制大对象
LONGBLOB 4,294,967,295字节 长二进制大对象

整数显示宽度与ZEROFILL

MySQL支持为整数类型指定显示宽度(如INT(5)),但不限制存储范围。ZEROFILL属性会用零填充到指定宽度。

ZEROFILL示例
CREATE TABLE zerofill_test (
    id INT(5) ZEROFILL
);
INSERT INTO zerofill_test VALUES (1), (123), (12345);
-- 显示结果:00001, 00123, 12345

其他类型

枚举类型(ENUM)

ENUM类型用于存储预定义的值列表中的一个值。

ENUM类型使用示例
CREATE TABLE enum_example (
    id INT,
    status ENUM('active', 'inactive', 'pending'),
    priority ENUM('low', 'medium', 'high')
);

集合类型(SET)

SET类型用于存储预定义的值列表中的零个或多个值。

SET类型使用示例
CREATE TABLE set_example (
    id INT,
    tags SET('red', 'green', 'blue', 'yellow')
);

-- 插入数据示例
INSERT INTO set_example (id, tags) VALUES (1, 'red,green');

JSON数据类型

MySQL 5.7.8+版本开始支持JSON数据类型,用于存储JSON格式的数据。

JSON类型使用示例
CREATE TABLE json_example (
    id INT,
    user_data JSON,
    preferences JSON
);

-- 插入JSON数据
INSERT INTO json_example (id, user_data) 
VALUES (1, '{"name": "John", "age": 30, "hobbies": ["reading", "swimming"]}');

-- JSON查询函数
SELECT JSON_EXTRACT(user_data, '$.name') FROM json_example;
SELECT user_data->>'$.name' FROM json_example;

JSON多值索引(MySQL 8.0.17+)

为JSON数组创建多值索引
-- 创建包含数组的JSON列
CREATE TABLE products (
    id INT PRIMARY KEY,
    tags JSON
);
-- 创建多值索引
CREATE INDEX idx_tags ON products ((CAST(tags->'$' AS CHAR(32) ARRAY)));

空间数据类型

MySQL支持空间数据类型,用于存储地理空间数据。

  • GEOMETRY - 所有空间类型的基类
  • POINT - 点
  • LINESTRING - 线
  • POLYGON - 多边形
  • MULTIPOINT - 多点
  • MULTILINESTRING - 多线
  • MULTIPOLYGON - 多多边形
  • GEOMETRYCOLLECTION - 几何集合

生成列(Generated Column)

生成列的值由其他列计算得出,支持VIRTUAL(默认)和STORED两种存储方式。

生成列示例
CREATE TABLE people (
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    full_name VARCHAR(101) GENERATED ALWAYS AS (CONCAT(first_name, ' ', last_name)) VIRTUAL,
    height_cm DECIMAL(5,2),
    height_inches DECIMAL(5,2) GENERATED ALWAYS AS (height_cm / 2.54) STORED
);

数据类型选择原则

  • 最小原则 - 选择能满足需求的最小数据类型
  • 简单原则 - 选择简单的数据类型,如整数比字符串处理更快
  • 避免NULL - 尽量使用NOT NULL约束,可以提高查询性能
  • 字符集选择 - 使用utf8mb4字符集以支持所有Unicode字符

数据类型对性能的影响

数据类型的选择直接影响数据库性能:

  • 存储空间 - 选择合适的数据类型可以减少存储空间
  • 索引效率 - 较小的数据类型索引效率更高
  • 查询性能 - 简单的数据类型处理更快
  • 内存使用 - 合理的数据类型可以减少内存使用

数据类型转换

MySQL支持隐式和显式数据类型转换:

数据类型转换示例
-- 隐式转换
SELECT '123' + 456;  -- 结果为579

-- 显式转换
SELECT CAST('123' AS UNSIGNED);
SELECT CONVERT('2023-01-01', DATE);

隐式转换的常见陷阱

可能导致性能问题的隐式转换
-- 错误:索引列与比较值类型不匹配,导致索引失效
SELECT * FROM users WHERE phone = 13800138000;  -- phone是VARCHAR,数字是INT

-- 正确:保持类型一致
SELECT * FROM users WHERE phone = '13800138000';

-- 日期比较:字符串与日期类型比较
SELECT * FROM orders WHERE order_date = '2023-01-01';  -- 可隐式转换但建议显式
SELECT * FROM orders WHERE order_date = DATE('2023-01-01');

数据类型与字符集

MySQL支持多种字符集,影响字符串类型的存储和比较:

  • utf8 - 支持大多数Unicode字符(3字节)
  • utf8mb4 - 支持所有Unicode字符(4字节)
  • latin1 - 西欧字符集
  • gbk - 简体中文字符集
字符集设置示例
-- 创建表时指定字符集
CREATE TABLE charset_example (
    id INT,
    name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

排序规则对查询的影响

不同的排序规则(Collation)影响字符串比较和排序结果:

  • utf8mb4_general_ci - 不区分大小写,性能较好
  • utf8mb4_unicode_ci - 遵循Unicode标准,更准确
  • utf8mb4_bin - 二进制比较,区分大小写和重音
排序规则示例
-- 不区分大小写
SELECT 'A' = 'a' COLLATE utf8mb4_general_ci;  -- 返回1

-- 区分大小写
SELECT 'A' = 'a' COLLATE utf8mb4_bin;  -- 返回0
注意:错误的数据类型选择会导致存储空间浪费、性能下降和数据不一致等问题。

数据类型最佳实践

  • 为标识符使用整数类型
  • 为金额使用DECIMAL类型
  • 为日期时间使用适当的日期时间类型
  • 为文本数据使用适当的字符串类型
  • 避免使用ENUM和SET类型,除非有特殊需求
  • 考虑使用JSON类型存储半结构化数据

下一步学习

了解了MySQL数据类型后,您可以继续学习: