MySQL数据库中的数据类型是数据库设计的基石,它们决定了数据的存储方式、数据的有效范围以及数据的处理方式。了解并合理使用MySQL的数据类型,对于提高数据库的性能、减少存储空间浪费以及保证数据的完整性至关重要。本文将详细介绍MySQL中的数据类型,包括数值类型、日期和时间类型、字符串类型等,并通过Markdown格式的表格进行展示。
数值类型用于存储数值数据,包括整数类型和浮点数类型。
MySQL中的整数类型一共有5种,包括TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)和BIGINT。每种整数类型都可以是有符号的(signed)或无符号的(unsigned),有符号整数可以表示正数和负数,而无符号整数只能表示正数和零。
数据类型 | 存储需求(字节) | 有符号取值范围 | 无符号取值范围 |
---|---|---|---|
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 | 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 |
示例:
CREATE TABLE tiny_example (
tiny_signed TINYINT, -- 有符号TINYINT
tiny_unsigned TINYINT UNSIGNED -- 无符号TINYINT
);
-- 插入数据
INSERT INTO tiny_example (tiny_signed, tiny_unsigned) VALUES (-128, 255);
INSERT INTO tiny_example (tiny_signed, tiny_unsigned) VALUES (127, 0);
-- 查询数据
SELECT * FROM tiny_example;
注释:tiny_signed列可以存储-128到127之间的整数,tiny_unsigned列可以存储0到255之间的整数。
CREATE TABLE small_example (
small_signed SMALLINT, -- 有符号SMALLINT
small_unsigned SMALLINT UNSIGNED -- 无符号SMALLINT
);
-- 插入数据
INSERT INTO small_example (small_signed, small_unsigned) VALUES (-32768, 65535);
INSERT INTO small_example (small_signed, small_unsigned) VALUES (32767, 0);
-- 查询数据
SELECT * FROM small_example;
注释:small_signed列可以存储-32768到32767之间的整数,small_unsigned列可以存储0到65535之间的整数。
CREATE TABLE medium_example (
medium_signed MEDIUMINT, -- 有符号MEDIUMINT
medium_unsigned MEDIUMINT UNSIGNED -- 无符号MEDIUMINT
);
-- 插入数据
INSERT INTO medium_example (medium_signed, medium_unsigned) VALUES (-8388608, 16777215);
INSERT INTO medium_example (medium_signed, medium_unsigned) VALUES (8388607, 0);
-- 查询数据
SELECT * FROM medium_example;
注释:medium_signed列可以存储-8388608到8388607之间的整数,medium_unsigned列可以存储0到16777215之间的整数。
CREATE TABLE int_example (
int_signed INT, -- 有符号INT
int_unsigned INT UNSIGNED -- 无符号INT
);
-- 插入数据
INSERT INTO int_example (int_signed, int_unsigned) VALUES (-2147483648, 4294967295);
INSERT INTO int_example (int_signed, int_unsigned) VALUES (2147483647, 0);
-- 查询数据
SELECT * FROM int_example;
注释:int_signed列可以存储-2147483648到2147483647之间的整数,int_unsigned列可以存储0到4294967295之间的整数。
CREATE TABLE big_example (
big_signed BIGINT, -- 有符号BIGINT
big_unsigned BIGINT UNSIGNED -- 无符号BIGINT
);
-- 插入数据
INSERT INTO big_example (big_signed, big_unsigned) VALUES (-9223372036854775808, 18446744073709551615);
INSERT INTO big_example (big_signed, big_unsigned) VALUES (9223372036854775807, 0);
-- 查询数据
SELECT * FROM big_example;
注释:big_signed列可以存储-9223372036854775808到9223372036854775807之间的整数,big_unsigned列可以存储0到18446744073709551615之间的整数。
MySQL允许在整数类型后面指定一个显示宽度(M),但这个显示宽度并不会影响整数的存储范围,只是用于在显示时填充字符以达到指定的宽度。
CREATE TABLE display_width_example (
id INT(5) ZEROFILL -- 指定显示宽度为5,并用0填充
);
-- 插入数据
INSERT INTO display_width_example (id) VALUES (123);
INSERT INTO display_width_example (id) VALUES (12345); -- 超过显示宽度但不会报错
-- 查询数据
SELECT * FROM display_width_example;
注释:在这个例子中,id列被指定为INT(5) ZEROFILL,所以当插入的数值小于5位时,会用0填充到5位。但是,如果插入的数值超过5位,它仍然会被正常存储,只是不会再填充0。需要注意的是,从MySQL 8.0.17开始,不推荐使用显示宽度属性。
UNSIGNED属性用于指定整数类型为无符号的,即只能存储非负整数。
CREATE TABLE unsigned_example (
unsigned_col INT UNSIGNED -- 无符号INT
);
-- 插入数据
INSERT INTO unsigned_example (unsigned_col) VALUES (-1); -- 插入负值会报错
INSERT INTO unsigned_example (unsigned_col) VALUES (4294967295);
-- 查询数据
SELECT * FROM unsigned_example;
注释:在这个例子中,尝试向unsigned_col列插入负值会报错,因为该列被指定为无符号的。
AUTO_INCREMENT属性用于生成唯一标识,通常用于主键字段。每次插入新行时,该字段的值会自动增加。
CREATE TABLE auto_increment_example (
id INT AUTO_INCREMENT PRIMARY KEY, -- 自动增长的主键
name VARCHAR(50)
);
-- 插入数据
INSERT INTO auto_increment_example (name) VALUES ('Alice');
INSERT INTO auto_increment_example (name) VALUES ('Bob');
-- 查询数据
SELECT * FROM auto_increment_example;
注释:在这个例子中,id列被指定为AUTO_INCREMENT,因此每次插入新行时,该列的值会自动增加。
浮点数类型用于存储带小数点的数值。MySQL提供了FLOAT和DOUBLE两种浮点数类型,以及定点数类型DECIMAL。
整数类型用于存储不带小数点的数值。MySQL提供了五种整数类型,它们的取值范围和存储需求各不相同。
数据类型 | 存储需求(字节) | 描述及精度 |
---|---|---|
FLOAT | 4或8 | 单精度浮点数,精度较低 |
DOUBLE | 8或16 | 双精度浮点数,精度较高 |
DECIMAL | M+2 | 定点数,精确存储,适用于需要高精度的数值计算,如货币计算 |
-- 创建一个表格来存储商品信息
CREATE TABLE products (
id INT PRIMARY KEY, -- 商品ID,主键
name VARCHAR(100), -- 商品名称
price FLOAT(7,2), -- 商品价格,使用FLOAT类型,总共7位数字,其中2位是小数
scientific_value DOUBLE, -- 科学计算值,使用DOUBLE类型
financial_value DECIMAL(10,2) -- 财务数据,使用DECIMAL类型,总共10位数字,其中2位是小数
);
-- 插入一些示例数据
INSERT INTO products (id, name, price, scientific_value, financial_value)
VALUES
(1, 'iPhone', 999.99, 1.23456789012345E+10, 1234567890.12),
(2, 'iPad', 699.99, 2.34567890123456E-10, 0.01),
(3, 'MacBook', 1299.99, -1.7976931348623157E+308, -9999999999.99);
-- 查询表格中的所有数据
SELECT * FROM products;
-- 创建一个表格来测试浮点数的比较
CREATE TABLE float_test (
id INT AUTO_INCREMENT PRIMARY KEY,
float_value FLOAT,
double_value DOUBLE
);
-- 插入一些浮点数数据
INSERT INTO float_test (float_value, double_value)
VALUES
(0.1, 0.1),
(0.2, 0.2),
(0.3, 0.3);
-- 比较浮点数是否相等
SELECT float_value, double_value, (float_value = double_value) AS is_equal
FROM float_test;
-- 使用一个小的阈值(epsilon)来判断两个浮点数是否相等
SET @epsilon = 0.00001;
SELECT float_value, double_value, (ABS(float_value - double_value) < @epsilon) AS is_equal_approx
FROM float_test;
关于FLOAT、DOUBLE和DECIMAL的更多信息,可以访问MySQL官方文档进行深入了解。
日期和时间类型用于存储日期和时间数据。MySQL提供了五种日期和时间类型。
数据类型 | 存储需求(字节) | 描述 |
---|---|---|
YEAR | 1 | 年份值,范围从1901到2155 |
TIME | 3 | 时间值,范围从’-838:59:59’到’838:59:59’ |
DATE | 3 | 日期值,范围从’1000-01-01’到’9999-12-31’ |
DATETIME | 8 | 日期和时间值,范围从’1000-01-01 00:00:00’到’9999-12-31 23:59:59’ |
TIMESTAMP | 4 | 时间戳,范围从’1970-01-01 00:00:01’ UTC到’2038-01-19 03:14:07’ UTC |
-- 创建一个名为events的表,用于存储事件信息
CREATE TABLE events (
id INT PRIMARY KEY, -- 事件ID,主键
event_name VARCHAR(100), -- 事件名称
event_date DATE, -- 事件日期,使用DATE类型
event_time TIME, -- 事件时间,使用TIME类型
event_datetime DATETIME, -- 事件日期和时间,使用DATETIME类型
event_timestamp TIMESTAMP, -- 事件时间戳,使用TIMESTAMP类型
event_year YEAR -- 事件年份,使用YEAR类型
);
-- 插入一些示例数据
INSERT INTO events (id, event_name, event_date, event_time, event_datetime, event_timestamp, event_year)
VALUES
(1, 'New Year Party', '2023-12-31', '23:59:59', '2023-12-31 23:59:59', CURRENT_TIMESTAMP, 2023),
(2, 'Daily Meeting', '2024-11-21', '10:00:00', '2024-11-21 10:00:00', '2024-11-21 10:00:00', 2024),
(3, 'Annual Conference', '2025-06-15', NULL, '2025-06-15 14:30:00', DEFAULT, 2025);
-- 查询表格中的所有数据
SELECT * FROM events;
-- 使用CURDATE()函数返回当前日期
SELECT CURDATE() AS today;
-- 使用CURTIME()函数返回当前时间
SELECT CURTIME() AS current_time;
-- 使用NOW()函数返回当前日期和时间
SELECT NOW() AS current_datetime;
-- 使用DATE_ADD()函数在日期上增加指定的时间间隔
SELECT DATE_ADD(CURDATE(), INTERVAL 7 DAY) AS next_week;
-- 使用DATE_FORMAT()函数将日期格式化为指定的格式
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS formatted_datetime;
字符串类型用于存储文本数据。MySQL提供了多种字符串类型,包括固定长度字符类型、可变长度字符类型、二进制字符串类型以及枚举类型和集合类型。
数据类型 | 存储需求(字节) | 描述 |
---|---|---|
CHAR | M(M为字符数) | 固定长度字符数据,如果存储的数据长度小于M,则会在右侧填充空格 |
-- 创建一个名为users的表,包含id、username和email字段
CREATE TABLE users (
id INT PRIMARY KEY, -- 用户ID,主键
username CHAR(20), -- 用户名,固定长度为20个字符
email CHAR(50) -- 电子邮件地址,固定长度为50个字符
);
-- 插入一些示例数据
INSERT INTO users (id, username, email)
VALUES
(1, 'john_doe', 'john.doe@example.com'),
(2, 'jane_smith', 'jane.smith@example.com'),
(3, 'alice_jones', 'alice.jones@example.com');
-- 查询表格中的所有数据
SELECT * FROM users;
-- 插入一个包含尾部空格的用户名
INSERT INTO users (id, username, email)
VALUES (4, 'bob_brown ', 'bob.brown@example.com'); -- 注意:'bob_brown '后面有3个空格
-- 查询并显示包含尾部空格的用户名
SELECT username, LENGTH(username) AS username_length FROM users WHERE id = 4;
-- 查询并显示去掉尾部空格后的用户名及其长度
SELECT TRIM(TRAILING ' ' FROM username) AS trimmed_username, LENGTH(TRIM(TRAILING ' ' FROM username)) AS trimmed_username_length FROM users WHERE id = 4;
数据类型 | 存储需求(字节) | 描述 |
---|---|---|
VARCHAR | M+1(M为字符数,+1用于存储长度信息) | 可变长度字符数据,只存储实际字符数和字符数据 |
-- 创建一个名为products的表,包含id、product_name和description字段
CREATE TABLE products (
id INT PRIMARY KEY, -- 产品ID,主键
product_name VARCHAR(100), -- 产品名称,最大长度为100个字符
description VARCHAR(500) -- 产品描述,最大长度为500个字符
);
-- 插入一些示例数据
INSERT INTO products (id, product_name, description)
VALUES
(1, 'Laptop', 'A high-performance laptop with 16GB RAM and 512GB SSD.'),
(2, 'Smartphone', 'A sleek and powerful smartphone with a 6.5-inch display.'),
(3, 'Headphones', 'Wireless over-ear headphones with noise cancellation.');
-- 查询表格中的所有数据
SELECT * FROM products;
-- 插入一个包含尾部空格的产品名称
INSERT INTO products (id, product_name, description)
VALUES (4, 'Keyboard ', 'A standard keyboard with 104 keys. '); -- 注意:'Keyboard '和'A standard keyboard with 104 keys. '后面都有空格
-- 查询并显示包含尾部空格的产品名称及其长度
SELECT product_name, LENGTH(product_name) AS product_name_length FROM products WHERE id = 4;
-- 更新产品名称,去掉尾部空格
UPDATE products SET product_name = TRIM(TRAILING ' ' FROM product_name) WHERE id = 4;
-- 查询更新后的产品名称及其长度
SELECT product_name, LENGTH(product_name) AS product_name_length FROM products WHERE id = 4;
-- 查询并显示VARCHAR字段存储的实际字节数(包括长度前缀)
-- 注意:这个查询是为了说明VARCHAR字段的存储机制,并不直接返回VARCHAR字段的存储大小,因为MySQL不直接暴露这个信息。
-- 在实际应用中,我们可以通过计算字符串长度和字符集来确定大致的存储空间。
SELECT id, product_name, LENGTH(product_name CHARACTER SET utf8mb4) +
CASE WHEN LENGTH(product_name CHARACTER SET utf8mb4) <= 255 THEN 1 ELSE 2 END AS storage_bytes
FROM products;
数据类型 | 存储需求(字节) | 描述 |
---|---|---|
TINYTEXT | 最多255字符 | 非常小的文本数据 |
TEXT | 最多65,535字符 | 小文本数据 |
MEDIUMTEXT | 最多16,777,215字符 | 中等大小的文本数据 |
LONGTEXT | 最多4,294,967,295字符 | 大文本数据 |
-- 创建一个名为articles的表,包含id、title和content字段
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT, -- 文章ID,主键,自增
title VARCHAR(255), -- 文章标题,最大长度为255个字符
content TEXT -- 文章内容,使用TEXT类型存储
);
-- 插入一些示例数据
INSERT INTO articles (title, content)
VALUES
('MySQL基础教程', 'MySQL是一种流行的关系型数据库管理系统,本文将介绍其基础知识。'),
('数据库索引优化', '数据库索引是提高查询性能的重要手段,本文将介绍索引的创建和优化方法。'),
('编程语言比较', '本文将比较几种流行的编程语言,包括Python、Java和C++。');
-- 查询表格中的所有数据
SELECT * FROM articles;
-- 插入一个包含较长文本内容的文章
INSERT INTO articles (title, content)
VALUES ('大数据与机器学习', '大数据和机器学习是当前技术领域的热门话题。本文将详细介绍大数据的基本概念、处理技术和机器学习算法,并探讨它们在实际应用中的结合方式。由于内容较长,此处仅为示例,实际内容可能包含更多细节和解释。');
-- 查询并显示包含较长文本内容的文章
SELECT title, content FROM articles WHERE id = 4;
-- 更新文章内容,添加更多细节
UPDATE articles
SET content = CONCAT(content, '此外,大数据和机器学习在医疗、金融、教育等领域也有广泛的应用。通过挖掘和分析大数据,可以发现隐藏的规律和模式,为决策提供有力支持。同时,机器学习算法可以自动学习和优化模型,提高预测和分类的准确性。')
WHERE id = 4;
-- 查询更新后的文章内容
SELECT title, content FROM articles WHERE id = 4 LIMIT 1; -- 使用LIMIT 1是为了避免输出过多数据,仅展示一条记录
数据类型 | 存储需求(字节) | 描述 |
---|---|---|
BINARY | M(M为字节数) | 固定长度二进制数据 |
VARBINARY | M+1(M为字节数,+1用于存储长度信息) | 可变长度二进制数据 |
TINYBLOB | 最多255字节 | 非常小的二进制大对象 |
BLOB | 最多65,535字节 | 小二进制大对象 |
MEDIUMBLOB | 最多16,777,215字节 | 中等大小的二进制大对象 |
LONGBLOB | 最多4,294,967,295字节 | 大二进制大对象 |
-- 创建一个名为binary_data的表,包含id和data字段
CREATE TABLE binary_data (
id INT PRIMARY KEY AUTO_INCREMENT, -- 数据ID,主键,自增
data BINARY(16) -- 二进制数据,固定长度为16字节
);
-- 插入一些示例数据(这里使用HEX函数将十六进制字符串转换为二进制数据)
INSERT INTO binary_data (data)
VALUES
(HEX_TO_BIN('4A6F686E20446F65')), -- 'John Doe'的ASCII码的十六进制表示,转换为二进制存储
(HEX_TO_BIN('4A616E6520446F65')), -- 'Jane Doe'的ASCII码的十六进制表示,转换为二进制存储
(HEX_TO_BIN('53616D75656C')); -- 'Samuel'的ASCII码的十六进制表示,转换为二进制存储
-- 查询表格中的所有数据(使用HEX函数将二进制数据转换回十六进制字符串以便显示)
SELECT id, HEX(data) AS hex_data FROM binary_data;
-- 创建一个名为variable_binary_data的表,包含id和data字段
CREATE TABLE variable_binary_data (
id INT PRIMARY KEY AUTO_INCREMENT, -- 数据ID,主键,自增
data VARBINARY(255) -- 可变长度的二进制数据,最大长度为255字节
);
-- 插入一些示例数据(这里直接使用BINARY关键字将字符串转换为二进制数据)
INSERT INTO variable_binary_data (data)
VALUES
(BINARY 'Short text'), -- 短文本数据
(BINARY 'A much longer piece of binary data that exceeds the length of the previous example.'), -- 长文本数据,超过之前的示例长度
(BINARY ''); -- 空二进制数据
-- 查询并显示包含二进制数据的记录
SELECT id, DATA_LENGTH(data) AS length, data AS binary_data_not_displayed -- 由于data是二进制数据,直接显示可能无意义,因此这里不直接显示data字段
FROM variable_binary_data;
-- 注意:由于data是二进制数据,直接SELECT data字段可能不会得到有意义的显示结果。
-- 在实际应用中,可能需要将二进制数据转换为可显示的格式(如十六进制字符串)或进行其他处理。
-- 这里我们使用DATA_LENGTH函数来显示二进制数据的长度。
-- 如果需要查看二进制数据的十六进制表示,可以使用以下查询:
SELECT id, HEX(data) AS hex_data FROM variable_binary_data;
ENUM: 枚举类型,允许从一个预定义的字符串集合中选择一个值。 SET: 集合类型,允许从一个预定义的字符串集合中选择多个值(类似于多选)。
更多关于MySQL字符串类型的详细信息,可以访问MySQL字符串类型官方文档进行了解。
MySQL 5.7及更高版本引入了JSON数据类型,用于存储JSON格式的数据。JSON数据类型允许存储和操作JSON对象、JSON数组等复杂的数据结构。
MySQL的空间数据类型用于存储和操作空间数据,如地理坐标、几何形状等。这些数据类型包括GEOMETRY、POINT、LINESTRING、POLYGON等。