字符串和二进制数据类型¶
本主题介绍 Snowflake 中支持的字符串/文本数据类型(包括二进制字符串),以及支持的字符串常量/字面量格式。
本主题内容:
文本字符串的数据类型¶
Snowflake 支持以下文本(即字符)字符串的数据类型。
VARCHAR¶
VARCHAR 存储 Unicode UTF-8 字符。
备注
在 Snowflake 之外的一些系统中, CHAR 和 VARCHAR 等数据类型存储 ASCII,而 NCHAR 和 NVARCHAR 等数据类型存储 Unicode。
在 Snowflake 中, VARCHAR 和所有其他字符串数据类型都存储 Unicode UTF-8 字符。CHAR 和 NCHAR 数据类型在 Unicode 处理方面没有区别。NCHAR 等同义词主要是为了将 DDL 命令移植到 Snowflake 时的语法兼容性。
当声明 VARCHAR 类型的列时,可以指定一个可选参数 (N)
,该参数是要存储的最大字符数。例如:
create table t1 (v varchar(16777216));
如果未指定长度,则默认值为允许的最大长度 (16,777,216)。
尽管 VARCHAR 的最大长度是以 字符 为单位指定的,但 VARCHAR 的最大 字节 数也受到限制 (16,777,216 (16 MB))。VARCHAR 列中可以存储的最大 Unicode 字符数如下所示:
- 单字节:
16,777,216。
- 多字节:
介于 8,388,608(每个字符 2 个字节)和 4,194,304(每个字符 4 个字节)之间。
例如,如果将一列声明为 VARCHAR (16777216),则该列最多可以容纳 8,388,608 个 2 字节 Unicode 字符,即使您指定了最大长度 16777216。
选择 VARCHAR 列的最大长度时,请考虑以下事项:
存储: 列仅使用实际存储数据量的存储空间。例如, VARCHAR (16777216) 列中的 1 个字符的字符串仅使用一个字符。
性能: 使用全长 VARCHAR 声明 VARCHAR (16777216) 和更短的长度没有性能差异。
请注意,在任何关系数据库中, WHERE 子句引用 VARCHAR 列或字符串列的 SELECT 语句都不如使用日期或数值列条件筛选的 SELECT 语句快。
处理数据的工具: 一些 BI/ETL 工具定义了存储或内存中 VARCHAR 数据的最大大小。如果您知道列的最大大小,则可以在添加列时限制该列的大小。
排序规则: 为 VARCHAR 列指定 排序规则 时,允许的字符数会有所不同,具体取决于每个字符占用的字节数和列的排序规则规范。
在比较排序列中的值时, Snowflake 遵循 Unicode 排序规则算法 (UCA)。此算法会影响允许的最大字符数。目前,使用最大大小和排序规则规范定义的 VARCHAR 列中允许大约 150 万到 800 万个字符。
例如,下表显示了 VARCHAR (16777216) 列的最大字符数如何变化,具体取决于每个字符的字节数和使用的排序规则规范:
每个字符的字节数
排序规则规范
允许的最大字符数(近似值)
1 个字节
en-ci
或en-ci-pi-ai
大约 700 万个字符
1 个字节
en
大约 400 万个字符
2 个字节
en-ci-pi-ai
大约 800 万个字符
2 个字节
en-ci
或en-ci-pi
大约 270 万个字符
2 个字节
en
大约 150 万个字符
CHAR、CHARACTER、NCHAR¶
与 VARCHAR 同义,只是如果未指定长度,则默认为 CHAR(1)。
备注
Snowflake 目前偏离了常见的 CHAR 语义,因为长度小于最大长度的字符串末尾没有空格填充。
STRING、TEXT、NVARCHAR、NVARCHAR2、CHAR VARYING、NCHAR VARYING¶
与 VARCHAR 同义。
表列中的字符串示例¶
CREATE OR REPLACE TABLE test_text(v VARCHAR,
v50 VARCHAR(50),
c CHAR,
c10 CHAR(10),
s STRING,
s20 STRING(20),
t TEXT,
t30 TEXT(30)
);
DESC TABLE test_text;
+------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
| name | type | kind | null? | default | primary key | unique key | check | expression | comment |
|------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------|
| V | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| V50 | VARCHAR(50) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| C | VARCHAR(1) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| C10 | VARCHAR(10) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| S | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| S20 | VARCHAR(20) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| T | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| T30 | VARCHAR(30) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
+------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
二进制字符串的数据类型¶
Snowflake 支持以下二进制字符串的数据类型。
BINARY¶
最大长度为 8 MB(8,388,608 个字节)。与 VARCHAR 不同, BINARY 数据类型没有 Unicode 字符的概念,因此长度始终以字节为单位。
(BINARY 值限制为 8 MB,以便在转换为十六进制字符串时不超过 16 MB,例如通过 TO_CHAR(<binary_expression>, 'HEX')
。)
如果未指定长度,则默认为最大长度。
VARBINARY¶
VARBINARY 是 BINARY 的同义词。
内部表示¶
BINARY 数据类型包含 8 位字节序列。
当 Snowflake 显示 BINARY 数据值时,Snowflake 通常将每个字节表示为 2 个十六进制字符。例如,单词“HELP”可能显示为 48454C50
,其中“48”是 ASCII (Unicode) 字母“H”的十六进制等效形式,“45”是字母“E”的十六进制表示形式,等等。
有关输入和显示 BINARY 数据的详情,请参阅:Binary Input and Output。
表列中的二进制示例¶
CREATE OR REPLACE TABLE test_binary(b BINARY,
b100 BINARY(100),
vb VARBINARY
);
DESC TABLE test_binary;
+------+-----------------+--------+-------+---------+-------------+------------+-------+------------+---------+
| name | type | kind | null? | default | primary key | unique key | check | expression | comment |
|------+-----------------+--------+-------+---------+-------------+------------+-------+------------+---------|
| B | BINARY(8388608) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| B100 | BINARY(100) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
| VB | BINARY(8388608) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL |
+------+-----------------+--------+-------+---------+-------------+------------+-------+------------+---------+
字符串常量¶
常量 (也称为 字面量)是指固定的数据值。Snowflake 中的字符串常量必须始终放在分隔符之间。Snowflake 支持使用以下任一方法分隔字符串常量:
单引号字符串常量¶
字符串常量可以放在单引号分隔符之间(例如 'This is a string'
)。若要在字符串常量中包含单引号字符,请键入两个相邻的单引号(例如 ''
)。
例如:
SELECT 'Today''s sales projections', '-''''-'; +------------------------------+----------+ | 'TODAY''S SALES PROJECTIONS' | '-''''-' | |------------------------------+----------| | Today's sales projections | -''- | +------------------------------+----------+
备注
两个单引号 不 同于双引号字符 ("
),双引号字符(根据需要)用于分隔对象标识符。有关更多信息,请参阅 标识符要求。
单引号字符串常量中的转义序列¶
若要在单引号字符串常量中包含单引号或其他特殊字符(例如换行符),必须使用 反斜杠转义序列 对这些字符进行转义。反斜杠转义序列是以反斜杠 (\
) 开头的字符序列。
备注
如果字符串包含许多单引号、反斜杠或其他特殊字符,您可以使用 美元引号字符串常量 来避免转义这些字符。
还可以使用转义序列来插入 ASCII 字符,方法是以八进制或十六进制形式指定它们的 代码点 (link removed) (对应于这些字符的数值)。例如,在 ASCII 中,空格字符的代码点为 32,十六进制为 20。要指定空格,可以使用十六进制转义序列 \x20
。
还可以使用转义序列插入 Unicode 字符,例如 \u26c4
。
下表列出了四个类别中支持的转义序列:简单、八进制、十六进制和 Unicode:
转义序列
表示的字符
简单转义序列
\'
单引号 (
'
) 字符
\"
双引号 (
"
) 字符
\\
反斜杠 (
\
) 字符
\b
退格字符
\f
换页符
\n
换行符
\r
回车符
\t
制表符
\0
ASCII NUL 字符
八进制转义序列
\ooo
八进制表示法中的 ASCII 字符(即每个
o
表示一个八进制数字)。十六进制转义序列
\xhh
十六进制表示法中的 ASCII 字符(即每个
h
表示一个十六进制数字)。Unicode 转义序列
\uhhhh
十六进制表示法中的 Unicode 字符(即每个
h
字符表示一个十六进制数字)。十六进制数字的数量必须正好是 4。
如上表所示,如果字符串常量必须包含反斜杠字符(例如 Windows 路径中的 C:\
或 正则表达式 中的 \d
),则必须用第二个反斜杠对反斜杠进行转义。例如,要在字符串常量的正则表达式中包含 \d
,必须使用 \\d
。
请注意,如果在上面列出的序列以外的序列中使用反斜杠,则将忽略反斜杠。例如,字符序列 '\z'
被解释为 'z'
。
下面的示例演示如何使用反斜杠转义序列。这包括指定以下内容的示例:
制表符
换行符
反斜杠
感叹号的八进制和十六进制转义序列(代码点 33,八进制为
\041
,十六进制为\x21
)雪人小图像的 Unicode 转义序列
不是有效转义序列的内容
SELECT $1, $2 FROM VALUES ('Tab','Hello\tWorld'), ('Newline','Hello\nWorld'), ('Backslash','C:\\user'), ('Octal','-\041-'), ('Hexadecimal','-\x21-'), ('Unicode','-\u26c4-'), ('Not an escape sequence', '\z') ; +------------------------+---------------+ | $1 | $2 | |------------------------+---------------| | Tab | Hello World | | Newline | Hello | | | World | | Backslash | C:\user | | Octal | -!- | | Hexadecimal | -!- | | Unicode | -⛄- | | Not an escape sequence | z | +------------------------+---------------+
以美元为引号的字符串常量¶
在某些情况下,可能需要指定一个包含以下内容的字符串常量:
单引号字符。
反斜杠字符(例如在 正则表达式 中)。
换行符(例如,在 CREATE PROCEDURE 或 CREATE FUNCTION 中指定的存储过程或函数的主体中)。
在这些情况下,可以使用一对美元符号 ($$
) 而不是单引号 ('
) 来分隔字符串的开头和结尾,从而避免 转义这些字符。
在以美元为引号的字符串常量中,可以包含引号、反斜杠、换行符和任何其他特殊字符(双美元符号除外),而无需转义这些字符。以美元符号括起的字符串常量的内容始终按字面含义解释。
以下示例是指定字符串常量的等效方法:
使用单引号分隔符的示例 |
使用双美元符号分隔符的示例 |
---|---|
'string with a \' character'
|
$$string with a ' character$$
|
'regular expression with \\ characters: \\d{2}-\\d{3}-\\d{4}'
|
$$regular expression with \ characters: \d{2}-\d{3}-\d{4}$$
|
'string with a newline\\ncharacter'
|
$$string with a newline
character$$
|
以下示例使用包含换行符和多个 转义序列 的带美元引号的字符串常量。
SELECT $1, $2 FROM VALUES ('row1', $$a ' \ \t \x21 z $ $$); +------+-------------------------------------------------------+ | $1 | $2 | |------+-------------------------------------------------------| | row1 | a | | | ' \ \t | | | \x21 z $ | +------+-------------------------------------------------------+
在此示例中,请注意如何将转义序列解释为它们的单个字符(例如,反斜杠后跟“t”),而不是转义序列。