MySQL中定义数据字段的类型对数据库的优化至关重要。正确选择数据类型可以提高查询性能、减少存储空间并确保数据完整性。MySQL支持多种数据类型,主要分为三类:数值类型、日期/时间类型和字符串类型。
MySQL支持所有标准SQL数值数据类型,包括严格数值类型和近似数值类型。
| 类型 | 字节数 | 有符号范围 | 无符号范围 | 描述 |
|---|---|---|---|---|
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 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0 到 18,446,744,073,709,551,615 | 大整数值 |
| 类型 | 字节数 | 描述 | 精度 |
|---|---|---|---|
FLOAT |
4 | 单精度浮点数 | 约7位小数 |
DOUBLE |
8 | 双精度浮点数 | 约15位小数 |
| 类型 | 描述 | 语法 |
|---|---|---|
DECIMAL |
精确的定点数 | DECIMAL(M, D) |
NUMERIC |
与DECIMAL相同 | NUMERIC(M, D) |
-- 创建包含各种数值类型的表
CREATE TABLE number_examples (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
age TINYINT UNSIGNED,
population BIGINT,
price DECIMAL(10, 2),
temperature FLOAT,
weight DOUBLE
);
-- 插入数据
INSERT INTO number_examples (age, population, price, temperature, weight)
VALUES (25, 1400000000, 99.99, 36.5, 65.75);
MySQL提供了多种日期和时间类型,用于存储时间相关的数据。
| 类型 | 字节数 | 格式 | 范围 | 描述 |
|---|---|---|---|---|
DATE |
3 | YYYY-MM-DD | 1000-01-01 到 9999-12-31 | 日期值 |
TIME |
3 | HH:MM:SS | -838:59:59 到 838:59:59 | 时间值 |
DATETIME |
8 | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 到 9999-12-31 23:59:59 | 日期和时间值 |
TIMESTAMP |
4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 到 2038-01-19 03:14:07 | 时间戳,自动更新 |
YEAR |
1 | YYYY | 1901 到 2155 | 年份值 |
-- 创建包含日期时间类型的表
CREATE TABLE datetime_examples (
id INT AUTO_INCREMENT PRIMARY KEY,
birth_date DATE,
meeting_time TIME,
created_at DATETIME,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
graduation_year YEAR
);
-- 插入数据
INSERT INTO datetime_examples (birth_date, meeting_time, created_at, graduation_year)
VALUES ('1990-05-15', '14:30:00', NOW(), 2024);
-- 查询示例
SELECT * FROM datetime_examples
WHERE birth_date > '1990-01-01';
MySQL提供了多种字符串类型,用于存储文本和二进制数据。
| 类型 | 最大长度 | 描述 | 存储特点 |
|---|---|---|---|
CHAR |
255字符 | 定长字符串 | 固定长度,不足补空格 |
VARCHAR |
65,535字符 | 变长字符串 | 可变长度,按实际数据存储 |
TINYTEXT |
255字节 | 短文本字符串 | 可变长度 |
TEXT |
65,535字节 | 文本字符串 | 可变长度 |
MEDIUMTEXT |
16,777,215字节 | 中等长度文本 | 可变长度 |
LONGTEXT |
4,294,967,295字节 | 长文本 | 可变长度 |
| 类型 | 最大长度 | 描述 |
|---|---|---|
BINARY |
255字节 | 定长二进制字符串 |
VARBINARY |
65,535字节 | 变长二进制字符串 |
TINYBLOB |
255字节 | 短二进制数据 |
BLOB |
65,535字节 | 二进制大对象 |
MEDIUMBLOB |
16,777,215字节 | 中等二进制数据 |
LONGBLOB |
4,294,967,295字节 | 长二进制数据 |
-- 枚举类型:只能选择预定义的值之一
CREATE TABLE enum_example (
id INT AUTO_INCREMENT PRIMARY KEY,
status ENUM('active', 'inactive', 'pending'),
priority ENUM('low', 'medium', 'high') DEFAULT 'medium'
);
-- 集合类型:可以选择多个预定义的值
CREATE TABLE set_example (
id INT AUTO_INCREMENT PRIMARY KEY,
tags SET('red', 'green', 'blue', 'yellow')
);
-- 插入数据
INSERT INTO enum_example (status, priority) VALUES ('active', 'high');
INSERT INTO set_example (tags) VALUES ('red,blue');
-- 创建包含字符串类型的表
CREATE TABLE string_examples (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
description TEXT,
avatar BLOB,
gender ENUM('male', 'female', 'other'),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入数据
INSERT INTO string_examples (username, email, description, gender)
VALUES ('john_doe', 'john@example.com', '这是一个用户描述文本。', 'male');
| 字符集 | 描述 | 推荐用途 |
|---|---|---|
utf8mb4 |
UTF-8 Unicode(4字节),支持所有Unicode字符包括emoji | 现代Web应用(强烈推荐) |
utf8 |
UTF-8 Unicode(3字节),不支持所有emoji | 旧系统兼容 |
latin1 |
西欧字符 | 仅需西欧语言的应用 |
gbk |
简体中文 | 中文环境 |
-- 数据库级别
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 表级别
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 列级别
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
description TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
);
-- 查看支持的字符集
SHOW CHARACTER SET;
-- 查看支持的排序规则
SHOW COLLATION WHERE Charset = 'utf8mb4';
-- 查看数据库的字符集
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA;
-- 查看表的字符集
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_database';
-- 错误:TINYINT溢出
INSERT INTO users (age) VALUES (300); -- TINYINT最大127
解决方案:选择合适范围的数值类型。
-- 错误:插入emoji字符
INSERT INTO users (name) VALUES ('😀'); -- 如果字符集不是utf8mb4
解决方案:使用utf8mb4字符集。
-- 错误:无效的日期格式
INSERT INTO events (event_date) VALUES ('2024-02-30');
解决方案:使用有效的日期值,MySQL会进行验证。
-- 警告:字符串被截断
INSERT INTO users (username) VALUES ('这是一个很长的用户名超过了定义的长度');
解决方案:为VARCHAR列指定足够的长度。
-- 用户表设计示例
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash CHAR(60) NOT NULL, -- bcrypt哈希固定60字符
first_name VARCHAR(50),
last_name VARCHAR(50),
birth_date DATE,
gender ENUM('male', 'female', 'other'),
phone_number VARCHAR(20),
avatar_url VARCHAR(255),
bio TEXT,
status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
credits DECIMAL(10, 2) UNSIGNED DEFAULT 0.00,
login_count INT UNSIGNED DEFAULT 0,
last_login_at DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_email (email),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;