搞清MySQL、Java、Redis的基本数据类型

54 阅读10分钟
  • 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年份YYYY1901 到 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中,一个字符占用的字节数并不是固定的,它取决于以下几个因素:

  1. 字符集(Character Set):不同的字符集对字符的编码方式不同,因此占用的字节数也不同。
  2. 具体存储的字符:特别是对于可变长度的字符集(如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 种基本数据类型,分为四类:整数型浮点型字符型布尔型。它们是语言内置的,不是对象。

数据类型大小范围或描述
byte1 byte-128 to 127
short2 bytes-32,768 to 32,767
int4 bytes-2^31 to 2^31-1
long8 bytes-2^63 to 2^63-1
float4 bytes约 6-7 位有效数字
double8 bytes约 15 位有效数字
char2 bytes'\u0000' to '\uffff'
booleanJVM 依赖true 或 false

注意:除了这 8 种基本类型,Java 还有对应的包装类(如 Integer, Double, Boolean),它们是对象,位于 java.lang 包中,用于集合操作或需要对象的场景。

4. Redis 基本数据类型

Redis 是一个键值存储系统,其“值”可以是多种数据结构。以下是 Redis 的五种核心数据类型:

类型命令前缀描述特点与应用场景
String (字符串)SETGETINCR最简单的类型,一个键对应一个字符串值。* 可以是文本、数字、二进制数据(如图片、序列化对象)。 * 支持对整数/浮点数进行原子增减 (INCRDECRINCRBYFLOAT)。 * 应用:缓存、计数器、分布式锁(SETNX)。
Hash (哈希)HSETHGETHGETALL一个键对应一个字段-值的映射表(类似 Java 的 Map<String, String>)。* 适合存储对象(如用户信息:user:1000 -> {name: "Alice", age: "30"})。 * 可以对单个字段进行操作,节省内存。
List (列表)LPUSHRPUSHLPOPRPOPLRANGE一个键对应一个有序的字符串列表,元素可重复。* 按插入顺序排序。 * 支持从两端插入/弹出元素(栈/队列)。 * 支持阻塞操作 (BLPOPBRPOP)。 * 应用:消息队列、最新消息列表、时间线。
Set (集合)SADDSMEMBERSSINTERSUNION一个键对应一个无序的、不重复的字符串集合。* 元素唯一。 * 支持集合运算:交集(SINTER)、并集(SUNION)、差集(SDIFF)。 * 应用:标签(Tagging)、共同好友、去重。
Sorted Set / ZSet (有序集合)ZADDZRANGEZRANKZSCORE一个键对应一个有序的、不重复的字符串集合,每个元素关联一个分数 (score) ,集合按分数排序。* 元素唯一,但分数可以相同(分数相同时按字典序排)。 * 支持范围查询、获取排名。 * 应用:排行榜、带权重的任务队列、延迟队列。

注意:Redis 的键(Key)本身也是字符串类型。