バイナリ入出力

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

このトピックの内容:

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

16進数(デフォルト)

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

始まり:

終わり:

メモ

バイナリ

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エンコーディングの詳細

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

  • 大文字(A~Z)

  • 小文字(a~z)

  • 10進数(0~9)

  • +

  • /

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

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

始まり:

終わり:

メモ

バイナリ

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

    パラメーターは、「HEX」、「BASE64」、または「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に設定することはできません。この状況で変換に UTF-8を使用するには、引数が2つのバージョンの TO_CHAR , TO_VARCHAR を使用します。

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

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

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

このオプションは、「HEX」、「BASE64」、または「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 TABLE binary_table (v VARCHAR, b BINARY);
INSERT INTO binary_table (v, b)
    SELECT 'AB', TO_BINARY('AB');
Copy
SELECT v, b FROM binary_table;
+----+----+
| V  | B  |
|----+----|
| AB | AB |
+----+----+
Copy

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

答えは、 TO_BINARY への引数は16進数のシーケンスとして扱われるということです(引用符で囲まれているため、文字列のように見えるとしても)。表示される2文字は実際には、2バイトの文字列データではなく、1バイトのバイナリデータを表す16進数のペアとして解釈されます。(入力の「文字列」に16進数以外の文字が含まれていた場合は、機能しなかったでしょう。「文字列「...」は、有効な16進数エンコードの文字列ではありません」といったエラーメッセージが表示されたはずです。)

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

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

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

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

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

CREATE TABLE demo_binary (b BINARY);
Copy

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

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

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

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

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

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

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

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

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

以下は、内部で何が起こっているかをより詳細に示すのに役立ちます。

SELECT 'HELP', HEX_ENCODE('HELP'), b, HEX_DECODE_STRING(HEX_ENCODE('HELP')),
   TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;
Copy

出力:

SELECT 'HELP', HEX_ENCODE('HELP'), b, HEX_DECODE_STRING(HEX_ENCODE('HELP')),
   TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+
| '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                             |
+--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+
Copy

BASE64 形式の例

このセクションを読む前に、上記の16進形式のセクションを読むことをお勧めします。基本的な概念は似ており、16進形式のセクションで詳細を説明しています。

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

CREATE TABLE demo_binary (b BINARY);
Copy

行を挿入します。

INSERT INTO demo_binary (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;
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+
| '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                                          |
+--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+
Copy

UTF-8形式の例

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

CREATE TABLE demo_binary (b BINARY);
Copy

行を挿入します。

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

その行を取得します。

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