字符串和二进制数据类型¶
本主题介绍 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 数据的详情,请参阅:二进制输入和输出。
表列中的二进制示例¶
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”),而不是转义序列。