字符串和二进制数据类型

本主题介绍 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));
Copy

如果未指定长度,则默认值为允许的最大长度 (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-cien-ci-pi-ai

    大约 700 万个字符

    1 个字节

    en

    大约 400 万个字符

    2 个字节

    en-ci-pi-ai

    大约 800 万个字符

    2 个字节

    en-cien-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    |
+------+-------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
Copy

二进制字符串的数据类型

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    |
+------+-----------------+--------+-------+---------+-------------+------------+-------+------------+---------+
Copy

字符串常量

常量 (也称为 字面量)是指固定的数据值。Snowflake 中的字符串常量必须始终放在分隔符之间。Snowflake 支持使用以下任一方法分隔字符串常量:

单引号字符串常量

字符串常量可以放在单引号分隔符之间(例如 'This is a string')。若要在字符串常量中包含单引号字符,请键入两个相邻的单引号(例如 '')。

例如:

SELECT 'Today''s sales projections', '-''''-';

+------------------------------+----------+
| 'TODAY''S SALES PROJECTIONS' | '-''''-' |
|------------------------------+----------|
| Today's sales projections    | -''-     |
+------------------------------+----------+
Copy

备注

两个单引号 同于双引号字符 ("),双引号字符(根据需要)用于分隔对象标识符。有关更多信息,请参阅 标识符要求

单引号字符串常量中的转义序列

若要在单引号字符串常量中包含单引号或其他特殊字符(例如换行符),必须使用 反斜杠转义序列 对这些字符进行转义。反斜杠转义序列是以反斜杠 (\) 开头的字符序列。

备注

如果字符串包含许多单引号、反斜杠或其他特殊字符,您可以使用 美元引号字符串常量 来避免转义这些字符。

还可以使用转义序列来插入 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             |
    +------------------------+---------------+
    
    Copy

以美元为引号的字符串常量

在某些情况下,可能需要指定一个包含以下内容的字符串常量:

在这些情况下,可以使用一对美元符号 ($$) 而不是单引号 (') 来分隔字符串的开头和结尾,从而避免 转义这些字符

在以美元为引号的字符串常量中,可以包含引号、反斜杠、换行符和任何其他特殊字符(双美元符号除外),而无需转义这些字符。以美元符号括起的字符串常量的内容始终按字面含义解释。

以下示例是指定字符串常量的等效方法:

使用单引号分隔符的示例

使用双美元符号分隔符的示例

'string with a \' character'
Copy
$$string with a ' character$$
Copy
'regular expression with \\ characters: \\d{2}-\\d{3}-\\d{4}'
Copy
$$regular expression with \ characters: \d{2}-\d{3}-\d{4}$$
Copy
'string with a newline\\ncharacter'
Copy
$$string with a newline
character$$
Copy

以下示例使用包含换行符和多个 转义序列 的带美元引号的字符串常量。

SELECT $1, $2 FROM VALUES ('row1', $$a
                                      ' \ \t
                                      \x21 z $ $$);

+------+-------------------------------------------------------+
| $1   | $2                                                    |
|------+-------------------------------------------------------|
| row1 | a                                                     |
|      |                                           ' \ \t      |
|      |                                           \x21 z $    |
+------+-------------------------------------------------------+
Copy

在此示例中,请注意如何将转义序列解释为它们的单个字符(例如,反斜杠后跟“t”),而不是转义序列。

语言: 中文