MariaDB数据类型 #
一、数据类型概述 #
1.1 类型分类 #
text
MariaDB数据类型
├── 数值类型
│ ├── 整数类型
│ │ ├── TINYINT
│ │ ├── SMALLINT
│ │ ├── MEDIUMINT
│ │ ├── INT
│ │ └── BIGINT
│ ├── 浮点类型
│ │ ├── FLOAT
│ │ └── DOUBLE
│ └── 定点类型
│ └── DECIMAL
├── 字符串类型
│ ├── CHAR
│ ├── VARCHAR
│ ├── TEXT系列
│ └── BLOB系列
├── 日期时间类型
│ ├── DATE
│ ├── TIME
│ ├── DATETIME
│ ├── TIMESTAMP
│ └── YEAR
├── JSON类型
│ └── JSON
├── 空间类型
│ ├── GEOMETRY
│ ├── POINT
│ ├── LINESTRING
│ └── POLYGON
└── 其他类型
├── BOOLEAN
├── ENUM
└── SET
二、整数类型 #
2.1 整数类型列表 #
| 类型 | 字节 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
| INT | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
| BIGINT | 8 | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 |
2.2 整数类型使用 #
sql
CREATE TABLE integers (
tiny_col TINYINT,
small_col SMALLINT,
medium_col MEDIUMINT,
int_col INT,
bigint_col BIGINT
);
INSERT INTO integers VALUES (127, 32767, 8388607, 2147483647, 9223372036854775807);
-- 无符号整数
CREATE TABLE unsigned_integers (
tiny_unsigned TINYINT UNSIGNED,
int_unsigned INT UNSIGNED
);
INSERT INTO unsigned_integers VALUES (255, 4294967295);
-- 显示宽度(不影响存储范围)
CREATE TABLE display_width (
num INT(5) ZEROFILL
);
INSERT INTO display_width VALUES (123);
-- 查询结果:00123
2.3 MariaDB特有整数类型 #
sql
-- MariaDB 10.5+ 支持 BOOLEAN 类型别名
CREATE TABLE bool_example (
is_active BOOLEAN -- 等同于 TINYINT(1)
);
-- 序列类型(MariaDB 10.3+)
CREATE TABLE sequence_example (
id INT AUTO_INCREMENT PRIMARY KEY
);
-- 使用序列引擎
CREATE TABLE seq ENGINE=SEQUENCE;
SELECT * FROM seq WHERE seq=1 FOR UPDATE;
2.4 选择建议 #
| 场景 | 推荐类型 |
|---|---|
| 年龄 | TINYINT UNSIGNED |
| 状态标识 | TINYINT |
| 数量、计数 | INT |
| 主键ID | INT 或 BIGINT |
| 金额(分) | BIGINT |
三、浮点类型 #
3.1 浮点类型列表 #
| 类型 | 字节 | 说明 |
|---|---|---|
| FLOAT | 4 | 单精度浮点数 |
| DOUBLE | 8 | 双精度浮点数 |
3.2 浮点类型使用 #
sql
CREATE TABLE float_table (
price FLOAT,
weight FLOAT(5,2),
precise_value DOUBLE(10,6)
);
INSERT INTO float_table VALUES (123.456, 123.45, 123.456789);
-- FLOAT(M,D)
-- M:总位数,D:小数位数
-- FLOAT(5,2):最多5位,小数2位,如:123.45
3.3 浮点精度问题 #
sql
-- 浮点数精度问题
SELECT 0.1 + 0.2 = 0.3; -- 结果:0(false)
-- 原因:浮点数存储有精度损失
SELECT 0.1 + 0.2; -- 结果:0.30000000000000004
-- 对于精确计算,使用DECIMAL
SELECT CAST(0.1 AS DECIMAL(10,1)) + CAST(0.2 AS DECIMAL(10,1)) = 0.3;
-- 结果:1(true)
四、定点类型 #
4.1 DECIMAL类型 #
sql
-- DECIMAL(M,D)
-- M:精度,总位数(1-65)
-- D:标度,小数位数(0-30)
CREATE TABLE decimal_table (
amount DECIMAL(10,2),
rate DECIMAL(5,4)
);
INSERT INTO decimal_table VALUES (12345678.90, 0.1234);
-- 精确计算
SELECT amount * rate FROM decimal_table;
-- 结果:精确值
4.2 金额存储 #
sql
-- 推荐方案1:DECIMAL存储
CREATE TABLE orders (
id INT PRIMARY KEY,
amount DECIMAL(10,2) -- 单位:元
);
-- 推荐方案2:整数存储(分)
CREATE TABLE orders_int (
id INT PRIMARY KEY,
amount BIGINT -- 单位:分,12345表示123.45元
);
-- 查询时转换
SELECT amount / 100 AS amount_yuan FROM orders_int;
五、字符串类型 #
5.1 CHAR和VARCHAR #
| 类型 | 说明 | 最大长度 | 特点 |
|---|---|---|---|
| CHAR(N) | 定长字符串 | 255 | 不足补空格 |
| VARCHAR(N) | 变长字符串 | 65535 | 按实际存储 |
sql
-- CHAR类型
CREATE TABLE char_table (
code CHAR(10),
status CHAR(1)
);
INSERT INTO char_table VALUES ('ABC', 'A');
-- code存储:'ABC '(补空格到10位)
-- VARCHAR类型
CREATE TABLE varchar_table (
name VARCHAR(100),
description VARCHAR(500)
);
INSERT INTO varchar_table VALUES ('John', 'This is a description');
-- name存储:'John'(4字节)
5.2 TEXT类型 #
| 类型 | 最大长度 | 存储需求 |
|---|---|---|
| TINYTEXT | 255字节 | 1字节前缀 |
| TEXT | 65535字节 | 2字节前缀 |
| MEDIUMTEXT | 16MB | 3字节前缀 |
| LONGTEXT | 4GB | 4字节前缀 |
sql
CREATE TABLE articles (
id INT PRIMARY KEY,
title VARCHAR(200),
summary TEXT,
content LONGTEXT
);
-- TEXT类型不能有默认值
-- 错误:content TEXT DEFAULT ''
5.3 BLOB类型 #
| 类型 | 最大长度 | 说明 |
|---|---|---|
| TINYBLOB | 255字节 | 小型二进制 |
| BLOB | 65KB | 二进制大对象 |
| MEDIUMBLOB | 16MB | 中型二进制 |
| LONGBLOB | 4GB | 大型二进制 |
sql
CREATE TABLE files (
id INT PRIMARY KEY,
file_name VARCHAR(100),
file_data MEDIUMBLOB,
file_size INT
);
-- 存储图片、文件等二进制数据
5.4 字符串类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 固定长度(如手机号) | CHAR |
| 变长字符串 | VARCHAR |
| 长文本 | TEXT |
| 二进制文件 | BLOB |
六、日期时间类型 #
6.1 日期时间类型列表 #
| 类型 | 格式 | 范围 | 字节 |
|---|---|---|---|
| DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 3 |
| TIME | HH:MM:SS | -838:59:59 ~ 838:59:59 | 3 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 8 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 | 4 |
| YEAR | YYYY | 1901 ~ 2155 | 1 |
6.2 DATE类型 #
sql
CREATE TABLE date_table (
birth_date DATE,
event_date DATE
);
INSERT INTO date_table VALUES ('1990-05-15', '2024-12-31');
-- 使用函数
INSERT INTO date_table VALUES (CURRENT_DATE, CURDATE());
-- 日期格式化
SELECT DATE_FORMAT(birth_date, '%Y年%m月%d日') FROM date_table;
-- 结果:1990年05月15日
6.3 TIME类型 #
sql
CREATE TABLE time_table (
start_time TIME,
duration TIME
);
INSERT INTO time_table VALUES ('09:30:00', '08:00:00');
-- 时间范围可以超过24小时(表示时长)
INSERT INTO time_table VALUES ('100:00:00', '200:30:00');
-- 使用函数
INSERT INTO time_table VALUES (CURRENT_TIME, NOW());
6.4 DATETIME类型 #
sql
CREATE TABLE datetime_table (
created_at DATETIME,
updated_at DATETIME
);
INSERT INTO datetime_table VALUES ('2024-01-15 10:30:00', NOW());
-- 自动初始化
CREATE TABLE auto_datetime (
id INT PRIMARY KEY,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
INSERT INTO auto_datetime (id) VALUES (1);
-- created_at和updated_at自动设置为当前时间
UPDATE auto_datetime SET id = 2 WHERE id = 1;
-- updated_at自动更新为当前时间
6.5 TIMESTAMP类型 #
sql
CREATE TABLE timestamp_table (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- TIMESTAMP特点:
-- 1. 自动转换为UTC存储
-- 2. 查询时转换为当前时区
-- 3. 范围受限(到2038年)
-- 查看时区设置
SHOW VARIABLES LIKE '%time_zone%';
-- 设置时区
SET time_zone = '+8:00'; -- 东八区
SET time_zone = 'SYSTEM'; -- 系统时区
6.6 MariaDB 10.3+ 微秒支持 #
sql
-- MariaDB支持微秒精度
CREATE TABLE microsecond_table (
id INT PRIMARY KEY,
created_at DATETIME(6) -- 6位微秒精度
);
INSERT INTO microsecond_table VALUES (1, '2024-01-15 10:30:00.123456');
SELECT created_at FROM microsecond_table;
-- 结果:2024-01-15 10:30:00.123456
6.7 日期函数 #
sql
-- 当前日期时间
SELECT NOW(), CURRENT_TIMESTAMP, SYSDATE();
SELECT CURDATE(), CURRENT_DATE;
SELECT CURTIME(), CURRENT_TIME;
-- 日期计算
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY); -- 加7天
SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH); -- 减1个月
SELECT DATEDIFF('2024-12-31', '2024-01-01'); -- 计算天数差
-- 提取部分
SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW());
SELECT HOUR(NOW()), MINUTE(NOW()), SECOND(NOW());
SELECT WEEKDAY(NOW()); -- 星期几(0=周一)
-- MariaDB特有函数
SELECT TO_SECONDS('2024-01-15'); -- 转换为秒数
SELECT SECONDS_TO_TIME(3600); -- 秒数转时间
七、JSON类型 #
7.1 JSON类型特点 #
sql
CREATE TABLE json_table (
id INT PRIMARY KEY,
data JSON
);
-- 插入JSON数据
INSERT INTO json_table VALUES (
1,
'{"name": "John", "age": 30, "skills": ["MySQL", "Python"]}'
);
-- 插入JSON数组
INSERT INTO json_table VALUES (
2,
'[{"id": 1, "name": "A"}, {"id": 2, "name": "B"}]'
);
7.2 JSON函数 #
sql
-- 提取值
SELECT data->'$.name' FROM json_table WHERE id = 1;
SELECT data->>'$.name' FROM json_table WHERE id = 1; -- 去掉引号
-- JSON_EXTRACT函数
SELECT JSON_EXTRACT(data, '$.name') FROM json_table;
-- 提取数组元素
SELECT data->'$.skills[0]' FROM json_table WHERE id = 1;
-- 创建JSON
SELECT JSON_OBJECT('name', 'John', 'age', 30);
-- 结果:{"name": "John", "age": 30}
SELECT JSON_ARRAY(1, 2, 3, 'a', 'b');
-- 结果:[1, 2, 3, "a", "b"]
-- 合并JSON
SELECT JSON_MERGE_PRESERVE(
'{"a": 1}',
'{"b": 2}'
);
-- 结果:{"a": 1, "b": 2}
-- 设置值
UPDATE json_table
SET data = JSON_SET(data, '$.email', 'john@example.com')
WHERE id = 1;
-- 删除值
UPDATE json_table
SET data = JSON_REMOVE(data, '$.age')
WHERE id = 1;
7.3 MariaDB增强JSON函数 #
sql
-- MariaDB 10.5+ JSON函数增强
-- JSON_VALUE(提取标量值)
SELECT JSON_VALUE('{"name": "John"}', '$.name');
-- 结果:John
-- JSON_TABLE(将JSON转为表)
SELECT * FROM JSON_TABLE(
'[{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]',
'$[*]' COLUMNS(
id INT PATH '$.id',
name VARCHAR(50) PATH '$.name'
)
) AS jt;
-- JSON_EXISTS(检查路径是否存在)
SELECT JSON_EXISTS('{"a": 1}', '$.a'); -- 1
SELECT JSON_EXISTS('{"a": 1}', '$.b'); -- 0
-- JSON_NORMALIZE(规范化JSON)
SELECT JSON_NORMALIZE('{"b":2,"a":1}');
-- 结果:{"a":1,"b":2}(按键排序)
7.4 JSON查询 #
sql
-- 按JSON字段查询
SELECT * FROM json_table WHERE data->'$.name' = '"John"';
-- 使用JSON_CONTAINS
SELECT * FROM json_table
WHERE JSON_CONTAINS(data->'$.skills', '"MySQL"');
-- 使用JSON_SEARCH
SELECT * FROM json_table
WHERE JSON_SEARCH(data, 'one', 'John') IS NOT NULL;
-- 创建虚拟列和索引
CREATE TABLE json_indexed (
id INT PRIMARY KEY,
data JSON,
name VARCHAR(100) AS (JSON_UNQUOTE(JSON_EXTRACT(data, '$.name'))) STORED,
INDEX idx_name (name)
);
八、枚举和集合 #
8.1 ENUM类型 #
sql
CREATE TABLE enum_table (
id INT PRIMARY KEY,
status ENUM('active', 'inactive', 'pending'),
priority ENUM('low', 'medium', 'high') DEFAULT 'medium'
);
INSERT INTO enum_table (id, status) VALUES (1, 'active');
-- ENUM存储为整数索引
-- 'active'=1, 'inactive'=2, 'pending'=3
-- 查询索引值
SELECT status + 0 FROM enum_table;
-- 查询所有可能值
SELECT DISTINCT status FROM enum_table;
-- 使用数字插入
INSERT INTO enum_table (id, status) VALUES (2, 2); -- 'inactive'
8.2 SET类型 #
sql
CREATE TABLE set_table (
id INT PRIMARY KEY,
tags SET('tag1', 'tag2', 'tag3', 'tag4')
);
-- 可以存储多个值
INSERT INTO set_table VALUES (1, 'tag1,tag2');
INSERT INTO set_table VALUES (2, 'tag1,tag2,tag3');
-- 使用FIND_IN_SET查询
SELECT * FROM set_table WHERE FIND_IN_SET('tag1', tags) > 0;
-- 使用位运算
SELECT * FROM set_table WHERE tags & 1; -- 包含tag1
九、布尔类型 #
9.1 BOOLEAN类型 #
sql
-- BOOLEAN是TINYINT(1)的别名
CREATE TABLE bool_table (
id INT PRIMARY KEY,
is_active BOOLEAN,
is_deleted BOOLEAN DEFAULT FALSE
);
INSERT INTO bool_table (id, is_active) VALUES (1, TRUE);
INSERT INTO bool_table (id, is_active) VALUES (2, FALSE);
-- 查询
SELECT * FROM bool_table WHERE is_active = TRUE;
SELECT * FROM bool_table WHERE is_active IS TRUE;
SELECT * FROM bool_table WHERE is_active;
十、空间类型 #
10.1 空间数据类型 #
sql
CREATE TABLE spatial_table (
id INT PRIMARY KEY,
location POINT,
route LINESTRING,
area POLYGON,
geometry GEOMETRY
);
-- 插入点
INSERT INTO spatial_table (id, location)
VALUES (1, POINT(116.404, 39.915));
-- 插入线
INSERT INTO spatial_table (id, route)
VALUES (2, LINESTRING(POINT(0,0), POINT(1,1), POINT(2,2)));
-- 插入多边形
INSERT INTO spatial_table (id, area)
VALUES (3, POLYGON(LINESTRING(POINT(0,0), POINT(0,1), POINT(1,1), POINT(1,0), POINT(0,0))));
10.2 空间函数 #
sql
-- 计算距离
SELECT ST_Distance(
POINT(116.404, 39.915),
POINT(121.474, 31.230)
);
-- 判断包含关系
SELECT ST_Contains(
POLYGON(LINESTRING(POINT(0,0), POINT(0,2), POINT(2,2), POINT(2,0), POINT(0,0))),
POINT(1,1)
);
-- 获取边界
SELECT ST_Boundary(
POLYGON(LINESTRING(POINT(0,0), POINT(0,1), POINT(1,1), POINT(1,0), POINT(0,0)))
);
十一、UUID类型 #
11.1 MariaDB 10.7+ UUID类型 #
sql
-- MariaDB 10.7+ 原生UUID类型
CREATE TABLE uuid_table (
id UUID DEFAULT UUID(),
name VARCHAR(100)
);
INSERT INTO uuid_table (name) VALUES ('John');
SELECT * FROM uuid_table;
-- id: 550e8400-e29b-41d4-a716-446655440000
-- UUID函数
SELECT UUID();
SELECT UUID_SHORT();
SELECT SYS_GUID(); -- Oracle兼容
11.2 旧版本UUID处理 #
sql
-- MariaDB 10.6及以下版本
CREATE TABLE uuid_compat (
id CHAR(36) DEFAULT UUID(),
name VARCHAR(100)
);
-- 或使用BINARY(16)存储
CREATE TABLE uuid_binary (
id BINARY(16) DEFAULT UNHEX(REPLACE(UUID(), '-', '')),
name VARCHAR(100)
);
-- 查询时转换
SELECT HEX(id) FROM uuid_binary;
SELECT UUID_FROM_BIN(id) FROM uuid_binary; -- MariaDB 10.8+
十二、类型转换 #
12.1 隐式转换 #
sql
-- 字符串转数字
SELECT '123' + 0; -- 结果:123
SELECT '123abc' + 0; -- 结果:123
-- 数字转字符串
SELECT CONCAT(123, 'abc'); -- 结果:'123abc'
-- 日期转换
SELECT '2024-01-01' + INTERVAL 1 DAY;
12.2 显式转换 #
sql
-- CAST函数
SELECT CAST('123' AS SIGNED);
SELECT CAST('123.45' AS DECIMAL(10,2));
SELECT CAST(123 AS CHAR);
SELECT CAST(NOW() AS DATE);
-- CONVERT函数
SELECT CONVERT('123', SIGNED);
SELECT CONVERT('abc' USING utf8mb4);
-- 常用转换
SELECT
CAST('2024-01-15' AS DATE),
CAST('10:30:00' AS TIME),
CAST('2024-01-15 10:30:00' AS DATETIME);
十三、类型选择建议 #
13.1 数值类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 主键 | INT / BIGINT / UUID |
| 年龄 | TINYINT UNSIGNED |
| 数量 | INT |
| 金额 | DECIMAL |
| 科学计算 | DOUBLE |
13.2 字符串类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 手机号 | CHAR(11) |
| 邮箱 | VARCHAR(100) |
| 用户名 | VARCHAR(50) |
| 文章内容 | TEXT |
| 文件数据 | BLOB |
13.3 时间类型选择 #
| 场景 | 推荐类型 |
|---|---|
| 出生日期 | DATE |
| 创建时间 | DATETIME / TIMESTAMP |
| 时区敏感 | TIMESTAMP |
| 持续时间 | TIME |
| 年份 | YEAR |
十四、总结 #
数据类型选择要点:
| 类型 | 选择原则 |
|---|---|
| 整数 | 根据范围选择最小类型 |
| 小数 | 精确计算用DECIMAL |
| 字符串 | 定长用CHAR,变长用VARCHAR |
| 日期 | 考虑时区和范围 |
| JSON | 灵活数据结构 |
| 空间 | 地理位置数据 |
下一步,让我们学习数据库操作!
最后更新:2026-03-27