バイナリ入出力

Snowflakeは、16進数、Base64、および UTF-8の3つのバイナリ形式またはエンコードスキームをサポートしています。

サポートされているバイナリ形式の概要

このセクションでは、サポートされているバイナリ形式について説明します。

16進数(デフォルト)

「16進数」形式は、16進数またはBase16システムを指します。この形式では、各バイトは2文字(0 から 9 の数字と A から F の文字)で表されます。16進数を使用して変換を実行する場合:

From

終わり

メモ

バイナリ

String

16進数は大文字を使用します。

String

バイナリ

16進数は大文字と小文字を区別しません。

16進数はデフォルトのバイナリ形式です。

Base64

「Base64」形式は、バイナリデータ(または文字列データ)を印刷可能な ASCII 文字(文字、数字、句読点または数学演算子)としてエンコードします。(Base64エンコードスキームは RFC 4648 で定義されています。)

Base64でエンコードされたデータには、次の利点があります。

  • Base64でエンコードされたデータは純粋な ASCII テキストであるため、 ASCII 文字データをサポートし、 BINARY データをサポートしないシステムに保存できます。たとえば、音楽(デジタルサンプル)を表すバイナリデータ、または北京語の文字を表す UTF データは、 ASCII テキストとしてエンコードし、 ASCII 文字のみをサポートするシステムに保存できます。

  • Base64でエンコードされたデータには制御文字(例: 送信終了文字、タブ文字)が含まれていないため、Base64でエンコードされたデータは、制御文字をデータとしてではなくコマンドとして理解されるリスクのない状態で送受信できます。Base64でエンコードされたデータは、一度に1文字ずつデータを送受信する古いモデムやその他の通信機器との互換性があります(パケットのどの部分がデータであり、どの部分がヘッダーまたは制御情報であるかを示すプロトコルはありません)。

Base64でエンコードされたデータには、次の欠点があります。

  • バイナリ表現と印刷可能な ASCII 表現の間でデータを変換すると、コンピューティングリソースを消費します。

  • Base64でエンコードされたデータには、元のデータよりも約1/3多くのストレージ容量が必要です。

以下のセクションでは、Base64エンコードの技術的な詳細を説明します。

Base64エンコーディングの詳細

3つの8ビットバイト(合計24ビット)のバイナリデータの各グループは、それぞれ6ビットの4つのグループ(依然24ビット)に再配置されます。6ビットの64の可能な組み合わせのそれぞれは、次の印刷可能な64の ASCII 文字のいずれかで表されます。

  • 大文字(A~Z)

  • 小文字(a~z)

  • 10進数(0~9)

  • +

  • /

さらに、入力の長さが3の正確な倍数でない場合は、 = という文字がパディングに使用されます。

Base64エンコードされたデータには空白文字(例: 空白や改行)が含まれないため、必要であればBase64エンコードされたデータに空白文字を混在させることができます。たとえば、送信側または受信側の行の長さに上限がある場合は、改行文字を追加することにより、データを破損することなくBase64でエンコードされたデータを個々の行に分割できます。Base64を使用して変換を実行する場合、

From

終わり

メモ

バイナリ

String

Base64は、空白や改行を挿入しません。

String

バイナリ

Base64は、すべての空白と改行を無視します。

UTF-8

UTF-8形式は、Unicodeの UTF-8文字エンコードを指します。

UTF-8は、テキストからバイナリへのエンコードに使用されます。すべての可能な BINARY 値を有効な UTF-8文字列に変換できるわけではないため、 UTF-8をバイナリからテキストへのエンコードに使用することはできません。

この形式は、実際のエンコードおよびデコードではなく、基になるデータを1つのタイプまたは別のタイプとして再解釈するために、バイナリとストリングの間の1対1変換を実行するのに便利です。

バイナリ値のセッションパラメーター

Snowflakeとの間でバイナリ値をやり取りする方法を決定する2つのセッションパラメーターがあります。

  • BINARY_INPUT_FORMAT: VARCHAR から BINARY に変換する関数への VARCHAR 入力の形式を指定します。これは次で使用されます。

    • 引数が1つのバージョンの TO_BINARY で BINARY への変換を実行します。

    • Snowflakeへのデータをロードします(ファイル形式のオプションが指定されていない場合。詳細は以下を参照)。

    パラメーターは、 HEXBASE64、 または UTF-8 (あるいは UTF8)に設定できます。パラメーター値は大文字と小文字を区別しません。デフォルトは HEX です。

  • BINARY_OUTPUT_FORMAT: BINARY から VARCHAR に変換する関数からの VARCHAR 出力の形式を指定します。これは次で使用されます。

    • 引数が1つのバージョンの TO_CHAR , TO_VARCHAR で VARCHAR への変換を実行します。

    • Snowflakeからデータをアンロードします(ファイル形式オプションが指定されていない場合。詳細は以下を参照)。

    • バイナリからvarcharへの変換が明示的に呼び出されていない場合に、人間が読める形式でバイナリデータを表示します(例: Snowflakeウェブインターフェイス)。

    パラメーターは、 HEX または BASE64 に設定できます。パラメーター値は大文字と小文字を区別しません。デフォルトは HEX です。

    注釈

    バイナリから文字列への変換は UTF-8形式では失敗する場合があるため、 BINARY_OUTPUT_FORMAT を UTF-8-8に設定することはできません。この状況で変換に UTF-8を使用するには、引数が2つのバージョンの TO_CHAR , TO_VARCHAR を使用します。

パラメーターは、アカウント、ユーザー、およびセッションレベルで設定できます。 SHOW PARAMETERS コマンドを実行して、現在のセッションのすべての操作に適用される現在のパラメーター設定を表示します。

バイナリ値をロード/アンロードするためのファイル形式オプション

バイナリ入力および出力セッションパラメーターとは別に、Snowflakeは BINARY_FORMAT ファイル形式のオプションを提供します。これを使用して、Snowflakeテーブルにデータをロードまたはアンロードするときにバイナリ形式を明示的に制御できます。

このオプションは、 HEXBASE64、または UTF-8 に設定できます(値は大文字と小文字を区別しません)。このオプションは、データのロードとアンロードの両方に影響し、他のファイル形式オプションと同様に、以下の方法で指定できます。

  • 名前付きファイル形式において、名前付きステージで参照、または COPY コマンドで直接参照できます。

  • 名前付きファイル形式において、名前付きステージで COPY コマンドで直接参照できます。

  • COPY コマンドで直接。

データのロード

データのロードに使用する場合、 BINARY_FORMAT はステージングされたデータファイルのバイナリ値の形式を指定します。このオプションは、セッションにある BINARY_INPUT_FORMAT パラメーターのあらゆる値セット(バイナリ値のセッションパラメーター を参照)を オーバーライド します。

このオプションが HEX または BASE64 に設定されている場合は、ステージングされたデータファイルの文字列が有効な16進数またはBase64でないと、データのロードに失敗することがあります。この場合、Snowflakeはエラーを返し、 ON_ERROR コピーオプションに指定されたアクションを実行します。

データのアンロード

データのアンロードで使用する場合、 BINARY_FORMAT オプションは、指定されたステージのファイルにアンロードされるバイナリ値に適用される形式を指定します。このオプションは、セッションにある BINARY_OUTPUT_FORMAT パラメーターのあらゆる値セット(バイナリ値のセッションパラメーター を参照)を オーバーライド します。

オプションが UTF-8 に設定されている場合、テーブルのバイナリ値に無効な UTF-8が含まれていると、データのアンロードは失敗します。この場合、Snowflakeはエラーを返します。

入力/出力の例

BINARY 入力/出力では、「表示されるものが必ずしも得られるわけではない」ため、混乱する可能性があります。

次の例を考えてみましょう:

CREATE OR REPLACE TABLE binary_table (v VARCHAR, b BINARY);

INSERT INTO binary_table (v, b)
  SELECT 'AB', TO_BINARY('AB');

SELECT v, b FROM binary_table;
Copy
+----+----+
| V  | B  |
|----+----|
| AB | AB |
+----+----+

v (VARCHAR)と列 b の出力は同一に見えます。しかし、 b 列の値はバイナリに変換されました。列 b の値が変わっていないように見えるのはなぜでしょうか。

それは、 TO_BINARY の引数が16進数の列として扱われるからです(引用符で囲まれているため文字列のように見えますが)。表示される2つの文字は、実際には2バイトの文字列データではなく、1バイトのバイナリデータを表す16進数のペアとして解釈されます。(入力の「文字列」に16進数以外の文字が含まれていた場合は、機能しなかったでしょう。 "String '...' isn't a legal hex-encoded string" といったエラーメッセージが表示されたはずです。)

また、 BINARY データが表示される場合、デフォルトでは16進数のシーケンスとして表示されます。したがって、データは(文字列ではなく)16進数として入力され、16進数として表示されるため、変更されていないように見えます。

実際のところ、2文字の文字列 AB を格納することが目標だった場合、コードは間違っていました。適切なコードは、データを保存する前に、関数 HEX_ENCODE を使用して文字列を16進数のシーケンスに変換します(または別の「エンコード」関数を使用してBase64などの別の形式に変換します)。その例を以下に示します。

16進数(「HEX」)形式の例

以下の例に示すとおり、 BINARY データを入力する1つの方法は、16進文字列としてエンコードすることです。

BINARY 列を持つテーブルの作成から始めます。

CREATE OR REPLACE TABLE demo_binary_hex (b BINARY);
Copy

TO_BINARY 関数を使用して「通常の」文字列を挿入し、有効な BINARY 値に変換しようとすると失敗します。

INSERT INTO demo_binary_hex (b) SELECT TO_BINARY('HELP', 'HEX');
Copy

エラーメッセージは次のとおりです。

100115 (22000): The following string is not a legal hex-encoded value: 'HELP'

今回は、入力を挿入前に明示的に16進数の文字列に変換します(これは成功する)。

INSERT INTO demo_binary_hex (b) SELECT TO_BINARY(HEX_ENCODE('HELP'), 'HEX');
Copy

次に、データを取得します。

SELECT TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary_hex;
Copy
+---------------+----------------------------------+
| TO_VARCHAR(B) | HEX_DECODE_STRING(TO_VARCHAR(B)) |
|---------------+----------------------------------|
| 48454C50      | HELP                             |
+---------------+----------------------------------+

ご覧のとおり、デフォルトでは出力は16進数で表示されます。元の文字列を取得するには、関数 HEX_DECODE_STRING (文字列のエンコードに以前に使用された関数 HEX_ENCODE の補数)を使用します。

以下のクエリは、内部で何が起こっているかをより詳細に示します。

SELECT 'HELP',
       HEX_ENCODE('HELP'),
       b,
       HEX_DECODE_STRING(HEX_ENCODE('HELP')),
       TO_VARCHAR(b),
       HEX_DECODE_STRING(TO_VARCHAR(b))
  FROM demo_binary_hex;
Copy
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+
| 'HELP' | HEX_ENCODE('HELP') | B        | HEX_DECODE_STRING(HEX_ENCODE('HELP')) | TO_VARCHAR(B) | HEX_DECODE_STRING(TO_VARCHAR(B)) |
|--------+--------------------+----------+---------------------------------------+---------------+----------------------------------|
| HELP   | 48454C50           | 48454C50 | HELP                                  | 48454C50      | HELP                             |
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+

BASE64 形式の例

このセクションを読む前に、 16進数(「HEX」)形式の例 をご参照ください。基本的なコンセプトは似ており、 16進数(「HEX」)形式の例 ではより詳しく説明されています。

BINARY 列を持つテーブルの作成から始めます。

CREATE OR REPLACE TABLE demo_binary_base64 (b BINARY);
Copy

行を挿入します。

INSERT INTO demo_binary_base64 (b) SELECT TO_BINARY(BASE64_ENCODE('HELP'), 'BASE64');
Copy

その行を取得します。

SELECT 'HELP',
       BASE64_ENCODE('HELP'),
       BASE64_DECODE_STRING(BASE64_ENCODE('HELP')),
       TO_VARCHAR(b, 'BASE64'),
       BASE64_DECODE_STRING(TO_VARCHAR(b, 'BASE64'))
 FROM demo_binary_base64;
Copy
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+
| 'HELP' | BASE64_ENCODE('HELP') | BASE64_DECODE_STRING(BASE64_ENCODE('HELP')) | TO_VARCHAR(B, 'BASE64') | BASE64_DECODE_STRING(TO_VARCHAR(B, 'BASE64')) |
|--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------|
| HELP   | SEVMUA==              | HELP                                        | SEVMUA==                | HELP                                          |
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+

UTF-8形式の例

BINARY 列を持つテーブルの作成から始めます。

CREATE OR REPLACE TABLE demo_binary_utf8 (b BINARY);
Copy

行を挿入します。

INSERT INTO demo_binary_utf8 (b) SELECT TO_BINARY('HELP', 'UTF-8');
Copy

その行を取得します。

SELECT 'HELP',
       TO_VARCHAR(b, 'UTF-8')
  FROM demo_binary_utf8;
Copy
+--------+------------------------+
| 'HELP' | TO_VARCHAR(B, 'UTF-8') |
|--------+------------------------|
| HELP   | HELP                   |
+--------+------------------------+