跳至主要内容

SQL 数据类型:新手必备指南

掌握 MySQL、PostgreSQL 与 SQL Server 中的 SQL 数据类型。学习如何选择合适的数值、文本与日期格式,以优化性能和数据完整性。
· 14分钟 阅读

使用 AI 探索

当您刚开始接触 SQL 时,很容易把数据类型当作简单的标签:一列要么存数字、要么存文本、日期,或者一些特殊类型。但数据类型并不只是标签,它是一组规则,定义了在数据库看来一个值“是什么”。

在实践中,数据类型决定了 SQL 如何“理解”数据库中的信息。它为 SQL 提供读取、比较和处理数据所需的上下文与指令,使其能够准确工作。

在本教程中,我们将了解 SQL 数据类型的主要类别,并看看它们在不同数据库管理系统中的表现。建议您结合示例一同练习。

如果您之前与数据库表打交道不多,我们的 SQL 基础课程能以清晰、对初学者友好的方式帮助您理解此类数据集的结构。

什么是 SQL 数据类型?

数据类型描述了数据的格式:一列可以包含哪些值、这些值如何在内部存储,以及对这些值可以执行哪些合理的操作。

这意味着您的数据类型选择不仅影响表设计,还会影响存储需求、查询性能、排序行为、数学运算,甚至不同系统对同一数值的解读方式。

下面是一个同时使用多种类型的简单表:

CREATE TABLE employees (
    id INT,
    name VARCHAR(50),
    start_date DATE,
    active BOOLEAN,
    salary DECIMAL(10, 2)
);

该表的每一列都定义了其可存储的数据类型。

  • id 列将存储整数,为每位员工提供唯一标识。

  • name 列可存放最多 50 个字符的文本,用于保存较短的姓名。

  • start_date 列用于日历日期。

  • active 列将存储 true 或 false,便于跟踪员工是否在职。

  • 最后,salary 列将存储带有 10 位精度的金额,小数点后保留两位表示分。

这些列共同构成了一个结构化的表,为每个字段允许的取值设定了规则,使数据更可预测、更易于处理。

让我们在 PostgreSQL 中添加一些示例数据,看看结果表会是什么样子。

INSERT INTO employees (id, name, start_date, active, salary)
VALUES
    (1, 'Alice Johnson', '2025-01-15', TRUE, 55000.00),
    (2, 'Bob Smith', '2024-06-01', FALSE, 62000.50);
    
SELECT *
FROM employees;

id

name

start_date

active

salary

1

Alice Johnson

2025-01-15

TRUE

55000.00

2

Bob Smith

2024-06-01

FALSE

62000.50

不同的数据库系统遵循相同原则,但在命名与特性上各有差异。例如,SQL Server 使用 BIT 代替 BOOLEAN,而 MySQL 将 BOOLEAN 视作一个小整数。

SQL 数据类型的类别

数据类型主要分为四类:数值、字符、日期与特殊类型。下面分别介绍。

Common SQL Data Types

数值数据类型

数值类型存储整数或小数。具体类型决定了可存储数值的范围、精度与占用空间。最常见的类型包括:

  • 整数类型,如 INT、SMALLINT 和 BIGINT,用于整数;

  • 定点小数,如 DECIMAL(p, s) 和 NUMERIC(p, s),用于精确小数值;

  • 浮点数,如 FLOAT 和 DOUBLE,用于近似值,可能引入微小的舍入差异。

我们创建一个示例表来演示不同的数值类型:

CREATE TABLE products (
    product_id INT,
    price DECIMAL(8, 2),
    measurement FLOAT
);

INSERT INTO products VALUES 
    (1, 19.99, 3.1415),
    (2, 250.56, 2.71828);

SELECT * FROM products;

以下是输出表的样子:

product_id

price

measurement

1

19.99

3.1415

2

250.56

2.71828

如您所见,第一列被限定为整数,第二列为小数点后两位的小数,第三列为小数点后位数不定的小数。

乍看之下,DECIMAL 与 FLOAT 似乎相同。但它们有一个重要区别:DECIMAL 以指定的小数位数精确存储数值,而 FLOAT 存储近似值,不同系统间可能略有差异。

当需要精确度时务必使用定点小数,而仅在可接受微小舍入误差时才依赖浮点数。

类别

数据类型

用途 / 存储内容

示例值

数值

INT、SMALLINT、BIGINT

不同范围的整数

1, 42, 1000

数值

DECIMAL(p,s)、NUMERIC(p,s)

具有固定精度的精确小数

19.99, 250.56

数值

FLOAT、DOUBLE

近似小数,可能引入轻微舍入差异

3.1415, 2.71828

字符与字符串数据类型

字符类型用于存储文本。不同类型在性能与存储效率上有所不同。

  • CHAR(n) 用于定长字符串。适合大小固定的数据,如州代码或机场缩写。

  • VARCHAR(n) 用于变长字符串。适用于姓名、电子邮件地址等用户输入文本。

  • TEXT 及相似类型用于大段非结构化文本,如博客文章或产品描述。

某些系统(如 SQL Server)还支持 Unicode 字符串类型,如 NCHAR 和 NVARCHAR,当您的数据包含多种文字体系(如拉丁文、中文或西里尔文)时非常有用。

类别

数据类型

用途 / 存储内容

示例值

字符 / 字符串

CHAR(n)

定长文本

'US','CA'

字符 / 字符串

VARCHAR(n)

变长文本

'Alice Johnson','Bob Smith'

字符 / 字符串

TEXT

大段非结构化文本

'Preferred contact by email.','Requires invoice copy for each order.'

字符 / 字符串

NCHAR(n)、NVARCHAR(n)

定长或变长的 Unicode 文本

'Å','É','München','São Paulo'

下面通过一个示例表来展示不同字符串数据类型的效果:

CREATE TABLE customers (
    id INT,
    country_code CHAR(2),
    name VARCHAR(100),
    notes TEXT
);

INSERT INTO customers VALUES
    (1, 'US', 'Alice Johnson', 'Preferred contact by email.'),
    (2, 'CA', 'Bob Smith', 'Requires invoice copy for each order.');
    
SELECT * FROM customers;

该表最终会呈现如下。您可以看到每种字符串数据类型在长度上的差异。

id

country_code

name

notes

1

US

Alice Johnson

Preferred contact by email.

2

CA

Bob Smith

Requires invoice copy for each order.

在此,CHAR(2) 强制固定长度,而 VARCHAR 与 TEXT 提供更大的灵活性。

日期与时间数据类型

日期与时间数据类型可以准确存储与查询时间信息。初学者可能会用数值或字符串来编码这类信息,但这会在后续数据分析中引发问题。使用专用的日历数据类型能让一切更顺畅。

最常用的三种类型是:

  • DATE,编码年、月、日;

  • TIME,存储时、分、秒;

  • DATETIME 或 TIMESTAMP,存储日期与时间的组合。

现代数据库甚至支持小数秒或时区感知的数据类型,例如 PostgreSQL 的 TIMESTAMPTZ,以 UTC 存储时间戳,并在检索时自动转换为您会话的时区。

类别

数据类型

用途 / 存储内容

示例值

日期 / 时间

DATE

日历日期(年、月、日)

'2025-11-26'

日期 / 时间

TIME

一天中的时间(时、分、秒)

'09:30:00','18:45:30'

日期 / 时间

DATETIME、TIMESTAMP

日期与时间的组合

'2025-11-20 14:15:00','2025-11-21 09:00:00'

日期 / 时间

TIMESTAMPTZ

带时区的日期时间(PostgreSQL)

'2025-11-21 09:00:00+00'

我们来创建一个简单的表来演示这些时间数据类型:

CREATE TABLE events (
    event_id INT,
    event_date DATE,
    start_time TIME,
    created_at DATETIME
);

INSERT INTO events VALUES
    (1, '2025-11-26', '09:30:00', '2025-11-20 14:15:00'),
    (2, '2025-12-01', '18:45:30', '2025-11-21 09:00:00');
    
SELECT * FROM events;

该表将显示如下:

event_id

event_date

start_time

created_at

1

2025-11-26

09:30:00

2025-11-20 14:15:00

2

2025-12-01

18:45:30

2025-11-21 09:00:00

您可以看到,选择正确的日期或时间戳类型会影响可存储的数据类型。

布尔与其他特殊数据类型

并非所有数据都能恰好归入前述类别。对于这些数据,SQL 提供了一组特殊用途的类型来支持特定场景。常见的包括:

  • 布尔值(BOOLEAN、BOOL 或 BIT,取决于系统)用于记录真或假;

  • 二进制数据(BLOB)用于图像、文件或序列化对象;

  • 大文本(CLOB)用于完整文档;

  • JSON(在 MySQL 与 PostgreSQL 中)用于无模式或嵌套数据;

  • ARRAY(仅 PostgreSQL)用于列表;

  • UUID 用于不依赖数值序列的唯一标识,如会话令牌或全局跟踪码。

当仅靠传统表结构无法充分表达数据结构时,特殊类型可以让您存储更丰富或更灵活的数据。

类别

数据类型

用途 / 存储内容

示例值

特殊 / 布尔 / 其他

BOOLEAN、BOOL、BIT

真或假值

TRUE,FALSE

特殊 / 布尔 / 其他

BLOB

大型二进制对象(图像、文件)

[binary image data]

特殊 / 布尔 / 其他

CLOB

大文本文档

'Full contract text...'

特殊 / 布尔 / 其他

JSON

结构化或嵌套数据

'{"name": "Alice"}'

特殊 / 布尔 / 其他

ARRAY

值的列表(仅限 PostgreSQL)

[1,2,3]

特殊 / 布尔 / 其他

UUID

全局唯一标识符

'550e8400-e29b-41d4-a716-446655440000'

不同系统中的 SQL 数据类型

各数据库管理系统在使用这些数据类型的细节上存在差异。尽管大类一致,但具体名称和行为在不同系统间并不相同。

不同系统根据各自的优先级设计数据类型,因此行为不同。有的差异很小,比如关键字不同;也有的会影响实际数据行为,如文本长度上限、布尔值的存储方式、是否支持特殊格式等。

MySQL 强调速度与简洁,因此对布尔值采用实用、轻量的方案,如 TINYINT(技术上以数字存储)。它更看重性能与广泛兼容性,而非严格的类型语义。

PostgreSQL 追求标准化与可扩展性,这体现在其提供真正的 BOOLEAN 类型,以及更丰富的数据类型选择,如 ARRAY 与 JSONB,可直接在列中存储结构化或嵌套数据。

SQL Server 面向企业环境中的可预测性能,并与微软生态深度集成,因此提供如 BIT(布尔)与 VARCHAR(MAX)(大文本)等强类型定义。

下表并列展示了三个主流 SQL 系统对常见概念的实现方式。

概念

MySQL

PostgreSQL

SQL Server

数值(整数)

使用 INT 作为通用整数

使用 INTEGER 作为整数

使用 INT 作为整数

定点 / 固定精度数值

使用 DECIMAL(p, s) 存储精确数值

使用 NUMERIC(p, s) 进行精确存储

使用 DECIMAL(p, s) 存储精确数值

常规长度文本字符串

使用 VARCHAR(n) 存储变长文本

使用 VARCHAR(n) 存储变长文本

使用 VARCHAR(n) 存储变长文本

大文本存储

使用 TEXT 存储长文本字段

使用 TEXT 存储长文本字段

使用 VARCHAR(MAX) 存储长文本字段

布尔值

以 TINYINT(1)(0 或 1)存储布尔

使用原生 BOOLEAN(true/false)

使用 BIT(0 或 1)表示布尔样数据

自增主键

使用 AUTO_INCREMENT 关键字

使用 SERIAL 或 IDENTITY 生成自增整数

使用 IDENTITY 生成自增整数

超大字符串

使用 LONGTEXT 存储极大文本

允许非常大的 VARCHAR(几乎无上限)

使用 VARCHAR(MAX) 存储大型或不设上限文本

JSON 存储

支持 JSON 存储结构化 JSON 数据

同时支持 JSON(文本)与 JSONB(二进制优化)

支持 JSON(以文本存储)

数组存储

不支持数组类型

支持 ARRAY 在单列中存储列表

不支持数组类型

这在实践中的意义

每个系统的底层设计目标以及其优化支持的工作负载类型,都会直接影响其运行方式。

这意味着,尽管许多常见的 SQL 技能可以在系统之间通用,但诸如文本最大长度、自增关键字或对复杂结构的支持等细节会有所不同。

如果您只使用一个系统,很容易熟悉该数据库管理系统的细枝末节。但更换工作或部门时,可能需要转向一套规则不同的系统。

因此,在学习 SQL 时,识别数据类型背后的共通概念要比仅依赖某一系统的特性更有帮助。

选择合适的数据类型

选择数据类型有时一目了然,有时则需要多想一想。合理的选择能让数据更易查询、存储更精简,并避免后续出现问题。大类通常由数据本身的性质决定。

数值数据

例如,假设您要存储测量数据,显然应选择某种数值类型,而不是日历或字符串。那么测量需要多精确?使用整数即可,还是需要小数?是否需要固定的有效位数?

接着要考虑存储与效率。选择能安全容纳数据的最小整数类型有助于提升表的效率。更小的类型占用更少存储,并能提升性能,尤其在大表中。通常应选择既能覆盖预期范围、又不过度冗余的类型。

当整数不适用时,可在 DECIMAL 与 FLOAT 之间选择。浮点类型存储的是近似值,可能导致在金融、科学或其他对精度敏感的场景中产生舍入误差。

DECIMAL 与 NUMERIC 存储精确值,更适合涉及价格或比率的场景。不过,DECIMAL 相比 FLOAT 通常需要更大的存储空间,具体取决于小数位数。

字符与字符串数据

对于字符串数据,您需要考虑每个输入的大小上限。

通常应根据实际情况设定 VARCHAR 的长度,而非一味取最大值。过大的上限并不会提升灵活性,反而可能误导后续开发者对数据预期规模的理解。

结合预期输入(如姓名、邮箱、产品标题等)合理设定列的长度。

日期与时间数据

对于日历数据,请明确您要存的是什么。

如果只需要日期或只需要时间,通常优先使用 DATE 或 TIME 而非 DATETIME。这些选择能清楚表达意图、减少混淆空间,并让数据库在仅日期或仅时间的查询上有更多优化空间。

布尔数据

尽量使用与领域匹配的原生类型,如 BOOLEAN,而不是用整数或字符串替代。原生类型自带校验、更清晰的语义,并得到期望特定数据类型的数据库函数的支持。

下表汇总了常见的数据存储目标及对应推荐的 SQL 数据类型,以满足需求。

目标

推荐数据类型

原因

存储精确数值(货币、测量)

DECIMAL 或 NUMERIC

避免浮点舍入问题,精确存储

存储短或中等长度文本

VARCHAR(n)

存储高效,长度灵活且大小可预期

存储长的非结构化文本

TEXT 或 CLOB

为描述或文档等大段文本而设计

仅存日期或仅存时间信息

DATE 或 TIME

避免不必要的复杂度,更贴合数据语义

存储灵活、类文档的值

JSON 或 JSONB

适合不适合固定列的嵌套或演进中的结构

如需回顾数据分组与筛选,推荐 中级 SQL课程,带您系统掌握这些核心技能。

常见陷阱与最佳实践

即使是简单的数据库模式,如果数据类型选择不当也会遇到问题。

截断

例如,如果姓名列只允许 5 个字符,可能会出现 “Micha” 而非 “Michael”。这就是常说的截断问题。

此类问题常见于姓名、地址或评论字段,真实世界的差异可能超出过于乐观的限制。避免方法之一是基于真实样本设定文本字段长度,或适度放宽。

舍入误差

另一类常见问题是将浮点数用于货币或其它高精度数据时出现意外舍入。由于 FLOAT 存储近似值,微小差异会积累并影响报表、汇总或计算。

可通过选择 DECIMAL 来避免这一问题,凡涉及货币或精确小数时优先使用定点类型,以确保数值稳定。

类型不匹配

类型不匹配也会导致查询变慢,尤其是在连接或比较时。

当一列存为字符串、另一列存为整数(或两表使用略有差异的类型)而您尝试连接它们时,数据库可能需要动态转换,既可能出错,也会增加不必要的开销。

让相关列在类型上保持一致,可以避免这些隐性转换,使查询更顺畅。

日期格式

日历日期自有其一套难题。

当系统混用本地化习惯,或开发者把日期存为字符串而非专用日期类型时,日期格式不一致会带来大量困扰,导致查询异常或静默地产生错误结果。

简单直接的解决办法是使用真实的日期类型,并在以文本形式处理日期时坚持使用一致、明确的格式。我强烈推荐我们的Time Series Analysis in SQL Server课程,帮助您避免数据库中最常见的日历问题。

最佳实践

以下做法有助于确保数据库顺畅运行:

  • 在设计早期用样本数据填充表,以暴露在尺寸或类型选择上的薄弱环节。

  • 为每一列记录用途与预期范围,避免后续更改引入不匹配。

  • 避免使用泛化类型;在更具体的类型能提升清晰度时优先使用它们。

结语

数据类型定义了数据库如何“理解”您存储的值。它们影响从存储到性能再到可读性的方方面面。掌握其工作方式能让数据库更可靠、更可预测。

想进一步阅读该主题,请查看 SQL 数据库概览教程以及 SQLite 数据类型:深入了解存储类。同时推荐 PostgreSQL 汇总统计与窗口函数课程,学习如何计算累计和与有序统计。

SQL 中的数据类型定义了一列可以存储的数据种类,以及这些数据在查询或处理时的行为。它影响存储、校验、排序、比较及数学运算。

SQL 数据类型常见问答

什么是 SQL 中的数据类型?

SQL 中的数据类型是一组规则,用来告知 SQL 您的列里将出现哪类信息。本质上,它是系统“理解”您数据的方式。

如何在 SQL 中为列设置特定的数据类型?

在 SQL 中定义列时,会在列名后立即指定数据类型,格式类似:name DATATYPE。您也可以使用 ALTER COLUMN 命令来更新已定义列的数据类型。

为什么需要选择正确的数据类型?

为您的数据选择合适的数据类型,能明确表达数据性质,确保正确的存储与使用,并防止后续代码出现问题。

DECIMAL 与 FLOAT 有何区别?

DECIMAL 是一种精确的数值数据类型,以固定的小数位存储数值;而 FLOAT 则存储该数值的近似值。

所有数据库管理系统都使用相同的数据类型吗?

算是也不算。各数据库管理系统在数值、字符与日历数据类型上有相似之处,但在具体名称、底层实现方式以及支持的特殊数据类型方面存在差异。

Amberle McKee

作者

Amberle McKee

我拥有博士学位,在生物研究环境中从事数据相关工作已有13年。我使用包括 Python、MATLAB 和 R 在内的多种编程语言开发软件。我热衷于与世界分享我对学习的热爱。

主题