跳转到内容

结构化查询语言/数据类型

来自维基教科书,开放的书籍,开放的世界



SQL 标准知道三种数据类型

  • 预定义数据类型
  • 构造类型
  • 用户定义类型。

此页面仅介绍预定义数据类型构造类型是数组、多重集、引用(引用)或行的其中之一。用户定义类型类似于面向对象语言中的类,具有自己的构造函数、观察器、变异器、方法、继承、重载、覆盖、接口等。

标准将预定义数据类型分组为具有相似特征的类型。

  • 字符类型
  • 字符(CHAR)
  • 可变字符(VARCHAR)
  • 字符大对象(CLOB)
  • 二进制类型
  • 二进制(BINARY)
  • 可变二进制(VARBINARY)
  • 二进制大对象(BLOB)
  • 数值类型
  • 精确数值类型(NUMERIC、DECIMAL、SMALLINT、INTEGER、BIGINT)
  • 近似数值类型(FLOAT、REAL、DOUBLE PRECISION)
  • 日期时间类型(DATE、TIME、TIMESTAMP)
  • 间隔类型(INTERVAL)
  • 布尔值
  • XML
  • JSON(自 SQL:2016

字符类型保存可打印字符,二进制类型保存任何二进制数据。两者都可以具有固定或可变大小,并具有上限。如果上限超过某个值,则该类型将成为具有特殊方法和函数的“大对象”。

精确数值类型保存没有小数点后数字或具有固定数量小数点后数字的数值。请注意,标准没有定义单独的数据类型“自动递增”来生成主键。相反,它在 CREATE TABLE 语句中定义了短语“GENERATED ALWAYS AS IDENTITY”,请参阅CREATE TABLE 语句自动递增列.

近似数值类型保存具有实现定义精度(小数点后)的数值。

时间类型保存 INTERVAL(时间轴上的某个范围)、DATE(年、月、日)、带有时区和不带有时区的 TIME(时区名称、小时、分钟、秒,包括小数部分)和带有时区和不带有时区的 TIMESTAMP(时区名称、年到秒,包括小数部分)的值。

布尔数据类型保存两个值truefalse

SQL 标准的第 14 部分通过引入数据类型 XML(Oracle 称之为 XMLType)以及大量特定函数,扩展了预定义数据类型的列表。此类型的列保存 XML 实例。

在过时的 SQL-2 标准中,存在数据类型“BIT”。此数据类型不再是标准的一部分。

大多数 DBMS 实现了大多数预定义数据类型,但存在一些例外。此外,命名略有不同。可以在维基教科书SQL_Dialects_Reference中找到主要实现的概述。

数据类型在 CREATE TABLE 语句中用作列定义的一部分,或在 CAST 操作期间使用。

CREATE TABLE <tablename> (
  <column_name> <data_type> ... ,
  <column_name> <data_type> ... ,
  ...
);

一系列可打印字符(即字符串)可以存储在字符字符串类型中。如果表的所有行都使用相同大小的字符串,则数据类型为CHAR(<n>),其中<n>是字符串的大小。如果大小在各行之间不同,则数据类型VARCHAR(<n>)定义了该列可以存储最多<n>个字符。因此,<n>定义了该列的上限。<n>的最大值取决于使用的 DBMS 实现。如果应用程序需要存储比此系统上限允许的更长的字符串,则必须使用数据类型CLOBCLOB也有自己的上限,但它明显大于VARCHAR的上限。

-- A table with columns of fixed and variable size strings and a CLOB string
CREATE TABLE datatypes_1 (
  id    DECIMAL PRIMARY KEY,
  col_1 CHAR(10),       -- exactly 10 characters
  col_2 VARCHAR(150),   -- up to 150 characters
  col_3 CLOB            -- very large strings (MySQL denotes this data type: 'LONGTEXT')
);

提示:与其他编程语言不同,SQL 不区分字符数据类型字符串数据类型。它只知道字符字符串数据类型 CHAR、VARCHAR 和 CLOB。

二进制

[编辑 | 编辑源代码]

二进制数据类型类似于字符数据类型。它们的不同之处在于它们接受不同的字节范围。二进制数据类型接受所有值。

-- A table with columns of fixed and variable size binary data and a BLOB
CREATE TABLE datatypes_2 (
  id    DECIMAL PRIMARY KEY,
  col_1 BINARY(10),     -- exactly 10 byte
  col_2 VARBINARY(150), -- up to 150 byte
  col_3 BLOB            -- very large data: jpeg, mp3, ...
);

针对 Oracle 用户的提示:数据类型BINARY不受支持,数据类型VARBINARY被表示为RAW并且已弃用。Oracle 建议使用BLOB

精确数值

[编辑 | 编辑源代码]

精确数值类型保存没有小数点后数字或具有固定数量小数点后数字的数值。所有精确数值类型都是有符号的。

NUMERIC(<p>,<s>)DECIMAL(<p>,<s>)表示两种几乎相同的类型。<p>(精度)定义了类型中所有数字的固定数量,而<s>(小数位数)定义了这些数字中哪些数字位于小数点后。小数点前超过 (p - s) 位的数值无法存储,小数点后超过 s 位的数值将被截断为小数点后 s 位。p 和 s 是可选的。它必须始终为:p ≥ s ≥ 0 且 p > 0。

SMALLINT、INTEGER 和 BIGINT 表示没有小数点的数据类型。SQL 标准没有定义它们的大小,但 SMALLINT 的大小应小于 INTEGER 的大小,INTEGER 的大小应小于 BIGINT 的大小。


-- A table using five exact numeric data types
CREATE TABLE datatypes_3 (
  id    DECIMAL PRIMARY KEY,
  col_1 DECIMAL(5,2),    -- three digits before the decimal and two behind
  col_2 SMALLINT,        -- no decimal point
  col_3 INTEGER,         -- no decimal point
  col_4 BIGINT           -- no decimal point. (Not supported by Oracle.)
);

近似数值

[编辑 | 编辑源代码]

近似数值类型保存具有实现定义精度(小数点后)的数值。所有近似数值类型都是有符号的。它们的主要用例是科学计算。

有三种类型:FLOAT (<p>)REALDOUBLE PRECISION,其中 p 表示FLOAT数据类型的保证精度。REALDOUBLE PRECISION的精度是实现定义的。

-- A table using the approximate numeric data types
CREATE TABLE datatypes_4 (
  id    DECIMAL PRIMARY KEY,
  col_1 FLOAT(2),     -- two or more digits after the decimal place
  col_2 REAL,
  col_3 DOUBLE PRECISION
);

与时间方面相关的數據类型是:DATE、TIME、TIMESTAMPINTERVAL

DATE存储年、月和日。TIME存储小时、分钟和秒。TIMESTAMP存储年、月、日、小时、分钟和秒。秒可以包含小数点后的数字。TIMETIMESTAMP可以包含时区名称。

SQL 标准定义了两种 INTERVAL。第一种是包含年和月的间隔,第二种是包含日、小时、分钟和秒的间隔。

-- A table using temporal data types
CREATE TABLE datatypes_5 (
  id    DECIMAL PRIMARY KEY,
  col_1 DATE,                       -- store year, month and day (Oracle: plus hour, minute and seconds) 
  col_2 TIME,
  col_3 TIMESTAMP(9),               -- a timestamp with 9 digits after the decimal of seconds
  col_4 TIMESTAMP WITH TIME ZONE,   -- a timestamp including the name of a timezone
  col_5 INTERVAL YEAR TO MONTH,
  col_6 INTERVAL DAY TO SECOND(6)   -- an interval with 6 digits after the decimal of seconds
);

针对 Oracle 用户的提示:数据类型TIME不受支持。请改用DATE

针对 MySQL 用户的提示:在数据类型中使用时区不受支持。MySQL 实现了不同的概念来处理时区。不支持秒的小数部分。数据类型INTERVAL不受支持,但存在数据值INTERVAL

布尔值

[编辑 | 编辑源代码]

SQL 具有三值逻辑。它知道布尔值truefalseunknown。布尔数据类型的列可以存储两个值truefalse中的一个。unknown通过不存储任何值来表示,这就是 NULL 指示符。

-- A table with one column of boolean
CREATE TABLE datatypes_6 (
  id    DECIMAL PRIMARY KEY,
  col_1 BOOLEAN     -- not supported by Oracle
);

SQL 标准的第 14 部分通过引入 XML 数据类型扩展了预定义数据类型的列表。该标准还为这种数据类型定义了广泛的特定函数。

-- A table with one column of data type XML 
CREATE TABLE datatypes_7 (
  id    DECIMAL PRIMARY KEY,
  col_1 XML
);

提示 Oracle 用户:XML 数据类型表示为 XMLType

提示 MySQL 用户:不支持 XML 数据类型。

在数据类型的上下文中,标准知道 *域*。域的目的是约束可以存储在列中的有效值的集合。域的概念是用户定义类型的早期前身,可能已经过时。

DROP TABLE datatypes_1;
DROP TABLE datatypes_2;
DROP TABLE datatypes_3;
DROP TABLE datatypes_4;
DROP TABLE datatypes_5;
DROP TABLE datatypes_6;
DROP TABLE datatypes_7;

创建一个名为“company”的表,其中包含列“id”(数字,主键)、“name”(最大长度为 200 的可变大小字符串)、“isin”(长度为 12 的字符串)、“stock_price”(小数点前 2 位,小数点后 2 位的数字)、“description_text”(非常大的字符串)和“description_doc”(任何二进制格式)。

点击查看解决方案
CREATE TABLE company (
  id               DECIMAL PRIMARY KEY,
  name             VARCHAR(200),
  isin             CHAR(12),
  stock_price      DECIMAL(4,2),
  description_text CLOB,
  description_doc  BLOB
);


华夏公益教科书