- MySQL:面向关系型数据库,数据类型侧重于结构化存储和数据完整性(如精确数值、日期、文本长度)。
- Java:作为编程语言,基本数据类型是内存中数据的直接表示,关注性能和底层操作。
- Redis:作为内存数据结构存储,其“数据类型”实际上是丰富的数据结构,强调操作的原子性和高性能的内存访问。
- 1kb = 1024字节(byte)、1字节 = 8bit
1. MySQL 基本数据类型
MySQL 的数据类型主要分为三大类:数值类型、串类型 和 日期时间类型。
- 数值类型
| 类型 | 描述 | 存储空间 | 范围/特点 |
|---|---|---|---|
BIT | 存储二进制序列 | 1 字节 | 可以指定 BIT 列的长度 M,即它能存储多少个二进制位:BIT(M)。M 的取值范围是 1 到 64。如果未指定 M,默认为 BIT(1),即只能存储 1 个位。(我目前还没用到过) |
TINYINT | 非常小的整数 | 1 字节 | -128 到 127 (有符号) / 0 到 255 (无符号) |
SMALLINT | 小整数 | 2 字节 | -32,768 到 32,767(有符号)/0~65535(无符号) |
MEDIUMINT | 中等大小的整数 | 3 字节 | -8,388,608 到 8,388,607(有符号)/0~16777215(无符号) |
INT / INTEGER | 标准整数 | 4 字节 | -2,147,483,648 到 2,147,483,647(有符号)/0~4294967295(无符号) |
BIGINT | 大整数 | 8 字节 | -2^63 到 2^63-1(有符号)/0~18446744073709551615(无符号) |
FLOAT | 单精度浮点数 | 4 字节 | 近似值,使用 FLOAT(p) 指定精度 |
DOUBLE | 双精度浮点数 | 8 字节 | 近似值,精度高于 FLOAT,CREATE TABLE data_with_precision_hint (id INT PRIMARY KEY,result FLOAT(53) -- 等同于 DOUBLE); |
DECIMAL(M,D) | 精确小数(定点数) | 可变 | 精确存储,常用于货币。M是总位数,D是小数位数 |
BOOLEAN | 布尔标记 | / | 为0或1,主要用于开/关标志 |
- 串类型
| 类型 | 描述 | 存储空间 | 特点 |
|---|---|---|---|
CHAR(N) | 定长字符串 | N 字节 | 固定长度,不足用空格填充,最大 255字符,长度必须在创建时指定,否则mysql默认char(1) |
VARCHAR(N) | 变长字符串 | L + 1 或 L + 2 字节 | 实际长度 + 长度标识,最大 65,535 字节(受行大小限制)。如果列的最大可能字节数不超过255,则长度标识1字节;否则2字节 |
TINYTEXT | 小文本 | 最大 255 字节 | |
TEXT | 文本 | 最大 65,535 字节 | 最大长度为64K的变长文本 |
MEDIUMTEXT | 中等文本 | 最大 16,777,215 字节 (~16MB) | 最大长度为16K |
LONGTEXT | 大文本 | 最大 4,294,967,295 字节 (~4GB) | 最大长度为4GB |
ENUM('val1','val2',...) | 枚举 | 1 或 2 字节 | 只能存储预定义列表中的一个值 |
SET('val1','val2',...) | 集合 | 1, 2, 3, 4 或 8 字节 | 可以存储预定义列表中的零个或多个值 |
例:创建一个包含 ENUM 列的表
-- 创建一个包含 ENUM 列的表
CREATE TABLE shirts (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
size ENUM('small', 'medium', 'large', 'x-large'), -- 预定义了4个值
color ENUM('red', 'green', 'blue', 'white', 'black') -- 预定义了5个值
);
-- 插入数据 (合法)
INSERT INTO shirts (name, size, color) VALUES
('Cotton T-shirt', 'medium', 'blue'),
('Wool Sweater', 'large', 'black'),
('Silk Shirt', 'small', 'white');
ENUM 在内部并不是直接存储字符串本身,而是存储一个数字索引。
MySQL 会自动为列表中的每个值分配一个从 1 开始的序号:
- `'val1'` -> 1
- `'val2'` -> 2
- `'val3'` -> 3
- ...
存储空间:
如果枚举列表包含 1 到 255 个值,MySQL 使用 1 字节 存储这个序号(因为 1 字节可以表示 1-255)。 如果枚举列表包含 256 到 65535 个值,MySQL 使用 2 字节 存储这个序号。
优势:这使得 ENUM 非常节省存储空间。无论 'very_long_option_name' 这个字符串有多长,它在数据库里只占 1 或 2 个字节。
- 日期时间类型
| 类型 | 描述 | 格式 | 范围/特点 |
|---|---|---|---|
DATE | 日期 | YYYY-MM-DD | '1000-01-01' 到 '9999-12-31' |
TIME | 时间 | HH:MM:SS[.fraction] | '-838:59:59' 到 '838:59:59' |
DATETIME | 日期和时间 | YYYY-MM-DD HH:MM:SS[.fraction] | '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59', **DATETIME(N)**表示精度,如DATETIME(6):2025-08-15 18:00:00.000001 |
TIMESTAMP | 时间戳 | YYYY-MM-DD HH:MM:SS[.fraction] | '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC。存储为 Unix 时间戳,受时区影响。 |
YEAR | 年份 | YYYY | 1901 到 2155,或 0000 |
目前接触好像用最多的是**DATETIME**,例:
CREATE TABLE events (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
-- 创建时间,通常自动填充为当前时间
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
-- 更新时间,更新记录时自动更新为当前时间
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- 事件发生的具体时间
event_time DATETIME,
-- 可以为 NULL 的 DATETIME
canceled_at DATETIME NULL
);
INSERT INTO events (title, event_time)
VALUES ('Urgent Task', NOW()); -- NOW() 返回当前的 DATETIME
2.MySQL 中一个字符占用的字节数
在MySQL中,一个字符占用的字节数并不是固定的,它取决于以下几个因素:
- 字符集(Character Set):不同的字符集对字符的编码方式不同,因此占用的字节数也不同。
- 具体存储的字符:特别是对于可变长度的字符集(如UTF-8),不同的字符可能占用不同的字节数。
- 常见的字符集及其存储情况:
- latin1:每个字符占用1个字节。适用于西欧语言。
- utf8:在MySQL中,
utf8字符集实际上是UTF-8编码的一个子集,每个字符占用1到3个字节。但注意,MySQL的utf8并不支持四字节的UTF-8字符(如一些表情符号),因此不推荐使用。 - utf8mb4:这是MySQL中完整的UTF-8实现,每个字符占用1到4个字节。它可以存储包括表情符号在内的所有Unicode字符。根据具体字符,占用字节数可以是1、2、3或4。
- gbk:每个字符占用2个字节(对于中文字符),但英文字符是1个字节。所以是可变长度,但范围是1到2字节。
- utf16:每个字符占用2或4个字节(代理对字符占用4字节)。
- ucs2:每个字符固定占用2个字节,但只能存储Unicode基本多语言平面(BMP)中的字符。
- ascii:每个字符占用1个字节,但仅支持ASCII字符(0-127)。
另外,对于可变长度的字符集(如utf8mb4),在存储时,实际占用的字节数取决于字符本身。例如:- 英文字符(ASCII字符)通常占用1个字节。- 欧洲语言中的带重音符号的字符、希腊文、阿拉伯文等通常占用2个字节。- 中文、日文、韩文等通常占用3个字节(在utf8mb4中,这些属于基本多文种平面,所以是3字节;而一些补充字符可能需要4字节)。- 表情符号和一些不常用的字符占用4个字节。
- MySQL中查看字符集和设置:
- 查看数据库的字符集:
SHOW CREATE DATABASE database_name; - 查看表的字符集:
SHOW CREATE TABLE table_name; - 查看列的字符集:`SHOW FULL COLUMNS FROM table_name;
- `另外,在定义列的时候,我们可以指定字符集,例如:
CREATE TABLE my_table (col1 VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci);
- 查看数据库的字符集:
- 计算存储空间:
-
对于
CHAR(N)类型,如果字符集是固定长度的(如ucs2),那么存储占用就是N*每个字符的字节数。 如果是可变长度(如utf8mb4),虽然存储的是可变长度,但MySQL会为CHAR类型分配固定长度的空间,这个空间是字符集可能的最大字节数乘以N。例如,
CHAR(10) CHARACTER SET utf8mb4,因为utf8mb4一个字符最多4字节,所以会占用40字节。但实际上,如果存储的内容都是单字节字符,那么实际存储可能只用了10字节,但占用存储空间还是40字节(因为CHAR是固定长度存储)。 -
对于
VARCHAR(N)类型,它存储的是可变长度,所以实际占用的空间是实际字符的字节数加上1或2个字节(用于记录长度)。具体来说,如果列的最大可能字节数不超过255,则额外1字节;否则额外2字节。因此,要准确知道“一个字符占用的字节数”,我们需要知道使用的字符集以及具体存储的字符。总结:在MySQL中,一个字符占用的字节数取决于字符集和实际存储的字符,范围从1字节到4字节不等。
-
3.Java 基本数据类型
Java 有 8 种基本数据类型,分为四类:整数型、浮点型、字符型 和 布尔型。它们是语言内置的,不是对象。
| 数据类型 | 大小 | 范围或描述 |
|---|---|---|
| byte | 1 byte | -128 to 127 |
| short | 2 bytes | -32,768 to 32,767 |
| int | 4 bytes | -2^31 to 2^31-1 |
| long | 8 bytes | -2^63 to 2^63-1 |
| float | 4 bytes | 约 6-7 位有效数字 |
| double | 8 bytes | 约 15 位有效数字 |
| char | 2 bytes | '\u0000' to '\uffff' |
| boolean | JVM 依赖 | true 或 false |
注意:除了这 8 种基本类型,Java 还有对应的包装类(如 Integer, Double, Boolean),它们是对象,位于 java.lang 包中,用于集合操作或需要对象的场景。
4. Redis 基本数据类型
Redis 是一个键值存储系统,其“值”可以是多种数据结构。以下是 Redis 的五种核心数据类型:
| 类型 | 命令前缀 | 描述 | 特点与应用场景 |
|---|---|---|---|
String (字符串) | SET, GET, INCR | 最简单的类型,一个键对应一个字符串值。 | * 可以是文本、数字、二进制数据(如图片、序列化对象)。 * 支持对整数/浮点数进行原子增减 (INCR, DECR, INCRBYFLOAT)。 * 应用:缓存、计数器、分布式锁(SETNX)。 |
Hash (哈希) | HSET, HGET, HGETALL | 一个键对应一个字段-值的映射表(类似 Java 的 Map<String, String>)。 | * 适合存储对象(如用户信息:user:1000 -> {name: "Alice", age: "30"})。 * 可以对单个字段进行操作,节省内存。 |
List (列表) | LPUSH, RPUSH, LPOP, RPOP, LRANGE | 一个键对应一个有序的字符串列表,元素可重复。 | * 按插入顺序排序。 * 支持从两端插入/弹出元素(栈/队列)。 * 支持阻塞操作 (BLPOP, BRPOP)。 * 应用:消息队列、最新消息列表、时间线。 |
Set (集合) | SADD, SMEMBERS, SINTER, SUNION | 一个键对应一个无序的、不重复的字符串集合。 | * 元素唯一。 * 支持集合运算:交集(SINTER)、并集(SUNION)、差集(SDIFF)。 * 应用:标签(Tagging)、共同好友、去重。 |
Sorted Set / ZSet (有序集合) | ZADD, ZRANGE, ZRANK, ZSCORE | 一个键对应一个有序的、不重复的字符串集合,每个元素关联一个分数 (score) ,集合按分数排序。 | * 元素唯一,但分数可以相同(分数相同时按字典序排)。 * 支持范围查询、获取排名。 * 应用:排行榜、带权重的任务队列、延迟队列。 |
注意:Redis 的键(Key)本身也是字符串类型。