Entrada e saída de binários¶
O Snowflake suporta três formatos binários ou esquemas de codificação: hexadecimal, base64 e UTF-8.
Neste tópico:
Visão geral dos formatos binários com suporte¶
hexadecimal (padrão)¶
O formato “hex” se refere ao sistema hexadecimal, ou base 16. Neste formato, cada byte é representado por dois caracteres (dígitos de 0 a 9 e letras de A
a F
). Ao utilizar o formato hexadecimal para realizar a conversão:
De: |
Para: |
Notas |
---|---|---|
Binário |
Cadeia de caracteres |
Hexadecimal usa letras maiúsculas. |
Cadeia de caracteres |
Binário |
Hexadecimal não diferencia maiúsculas e minúsculas. |
Hexadecimal é o formato binário padrão.
base64¶
O formato “base64” codifica dados binários (ou dados de cadeia de caracteres) como caracteres ASCII imprimíveis (letras, dígitos e pontuação ou operadores matemáticos). (O esquema de codificação base64 está definido em RFC 4648.)
Os dados codificados com base64 têm as seguintes vantagens:
Como os dados codificados com base64 são texto ASCII puro, eles podem ser armazenados em sistemas que suportam dados de caracteres ASCII, mas não dados
BINARY
. Por exemplo, dados binários que representam música (amostras digitais), ou dados UTF que representam caracteres do mandarim, podem ser codificados como texto ASCII e armazenados em sistemas que suportam apenas caracteres ASCII.Como os dados codificados com base64 não contêm caracteres de controle (por exemplo, caracteres de fim de transmissão, caracteres de tabulação), os dados codificados com base64 podem ser transmitidos e recebidos sem o risco de que os caracteres de controle possam ser interpretados como comandos e não como dados. Os dados codificados com base64 são compatíveis com modems antigos e outros equipamentos de telecomunicações que transmitem e recebem dados um caractere de cada vez (sem cabeçalhos de pacotes ou protocolos que indicam quais partes de um pacote são dados e quais são informações de cabeçalho ou de controle).
Os dados codificados com base64 têm as seguintes desvantagens:
A conversão de dados entre representações binárias e ASCII imprimíveis consome recursos computacionais.
Os dados codificados com base64 requerem aproximadamente 1/3 mais espaço de armazenamento do que os dados originais.
Os detalhes técnicos sobre a codificação estão abaixo para os leitores interessados:
Detalhes da codificação base64¶
Cada grupo de três bytes de 8 bits (um total de 24 bits) de dados binários é reordenado em quatro grupos de 6 bits cada (ainda 24 bits). Cada uma das 64 combinações possíveis de 6 bits é representada por um dos seguintes 64 caracteres ASCII imprimíveis:
letras maiúsculas (A - Z)
letras minúsculas (a - z)
dígitos decimais (0 - 9)
+
/
Além disso, o caractere =
é usado para enchimento se o comprimento da entrada não for um múltiplo exato de 3.
Como os dados codificados com base64 não contêm caracteres de espaço em branco (por exemplo, espaços vazios e quebras de linha), os dados codificados com base64 podem ser misturados com espaços em branco, se desejado. Por exemplo, se o transmissor ou receptor tiver um limite máximo para o comprimento da linha, os dados codificados com base64 podem ser divididos em linhas individuais adicionando caracteres de nova linha sem corromper os dados. Ao utilizar o formato de base64 para realizar a conversão:
De: |
Para: |
Notas |
---|---|---|
Binário |
Cadeia de caracteres |
base64 não insere nenhum espaço em branco ou quebra de linha. |
Cadeia de caracteres |
Binário |
base64 ignora todos os espaços em branco e quebras de linha. |
UTF-8¶
O formato UTF-8 refere-se à codificação de caracteres UTF-8 para Unicode.
UTF-8 é usado para codificação de texto para binário. UTF-8 não pode ser usado para codificação de binário para texto porque nem todos os valores BINARY possíveis podem ser convertidos em cadeias de caracteres UTF-8 válidas.
Este formato é conveniente para realizar a conversão um-para-um entre binário e cadeia de caracteres, para reinterpretar os dados subjacentes como um tipo ou outro, em vez de realmente codificar e decodificar.
Parâmetros de sessão para valores binários¶
Há dois parâmetros de sessão que determinam como os valores binários são passados de e para o Snowflake:
- BINARY_INPUT_FORMAT:
Especifica o formato da entrada VARCHAR para funções que convertem de VARCHAR para BINARY. É utilizado para:
Realizar a conversão para BINARY na versão de um único argumento de TO_BINARY.
Carregar dados no Snowflake (se nenhuma opção de formato de arquivo for especificada; consulte abaixo para detalhes).
O parâmetro pode ser definido como “HEX”, “BASE64” ou “UTF-8” (“UTF8” também é permitido). Os valores dos parâmetros não diferenciam maiúsculas e minúsculas. O padrão é “HEX”.
- BINARY_OUTPUT_FORMAT:
Especifica o formato da saída VARCHAR para funções que convertem de BINARY para VARCHAR. É utilizado para:
Realizar a conversão para VARCHAR na versão de um único argumento de TO_CHAR , TO_VARCHAR.
Descarregar dados do Snowflake (se nenhuma opção de formato de arquivo for especificada; consulte abaixo para detalhes).
Exibir dados binários em formato legível por humanos (por exemplo, na interface da Web do Snowflake) quando nenhuma conversão de binário em varchar tiver sido chamada explicitamente.
O parâmetro pode ser definido como “HEX” ou “BASE64”. Os valores dos parâmetros não diferenciam maiúsculas e minúsculas. O padrão é “HEX”.
Nota
Como a conversão de binário para cadeia de caracteres pode falhar com o formato UTF-8, BINARY_OUTPUT_FORMAT não pode ser definido com UTF-8. Para usar UTF-8 para conversão nesta situação, use a versão de dois argumentos de TO_CHAR , TO_VARCHAR.
Os parâmetros podem ser definidos nos níveis de conta, usuário e sessão. Execute o comando SHOW PARAMETERS para visualizar as configurações de parâmetros atuais que se aplicam a todas as operações na sessão atual.
Opção de formato de arquivo para carregar/descarregar valores binários¶
Separado dos parâmetros de sessão de entrada e saída binárias, o Snowflake fornece a opção de formato de arquivo BINARY_FORMAT, que pode ser usada para controlar explicitamente a formatação binária ao carregar ou descarregar dados das tabelas do Snowflake.
Esta opção pode ser definida como “HEX”, “BASE64” ou “UTF-8” (os valores não diferenciam maiúsculas de minúsculas). A opção afeta tanto o carregamento quanto o descarregamento de dados e, semelhante a outras opções de formato de arquivo, pode ser especificada de várias maneiras:
Em um formato de arquivo nomeado, que pode então ser referenciado em um estágio nomeado ou diretamente em um comando COPY.
Em uma etapa nomeada, que pode então ser referenciada diretamente em um comando COPY.
Diretamente em um comando COPY.
Carregamento de dados¶
Quando usado para o carregamento de dados, BINARY_FORMAT especifica o formato dos valores binários em seus arquivos de dados preparados. Esta opção substitui qualquer valor definido para o parâmetro BINARY_INPUT_FORMAT na sessão (consulte Parâmetros de sessão para valores binários acima).
Se a opção for definida como “HEX” ou “BASE64”, o carregamento de dados pode falhar se as cadeias de caracteres no arquivo de dados preparado não forem hexadecimais ou base64 válidas. Neste caso, o Snowflake retorna um erro e então executa a ação especificada para a opção de cópia ON_ERROR.
Descarregamento de dados¶
Quando utilizada no descarregamento de dados, a opção BINARY_FORMAT especifica o formato aplicado aos valores binários descarregados nos arquivos no estágio especificado. Esta opção substitui qualquer valor definido para o parâmetro BINARY_OUTPUT_FORMAT na sessão (consulte Parâmetros de sessão para valores binários acima).
Se a opção for definida como UTF-8, o descarregamento de dados falha se algum valor binário na tabela contiver valores UTF-8 inválidos. Neste caso, o Snowflake retorna um erro.
Exemplo de entrada/saída¶
A entrada/saída BINARY
pode ser confusa porque “o que você vê não é necessariamente o que recebe”.
Considere, por exemplo, a seguinte sequência de código:
CREATE TABLE binary_table (v VARCHAR, b BINARY); INSERT INTO binary_table (v, b) SELECT 'AB', TO_BINARY('AB');SELECT v, b FROM binary_table; +----+----+ | V | B | |----+----| | AB | AB | +----+----+
As saídas para a coluna v (VARCHAR) e para a coluna b parecem ser idênticas. No entanto, o valor para a coluna b foi convertido em binário. Por que o valor na coluna b parece inalterado?
A resposta é que o argumento para TO_BINARY
é tratado como uma sequência de dígitos hexadecimais (embora esteja dentro de aspas e, portanto, pareça uma cadeia de caracteres); os 2 caracteres que você vê são na verdade interpretados como um par de dígitos hexadecimais que representam 1 byte de dados binários, e não 2 bytes de dados de cadeia de caracteres. (Isto não teria funcionado se a “cadeia de caracteres” de entrada tivesse outros caracteres além de dígitos hexadecimais; o resultado teria sido uma mensagem de erro semelhante a “String “…” is not a legal hex-encoded string”).
Além disso, quando dados BINARY são exibidos, aparecem por padrão como uma sequência de dígitos hexadecimais. Assim, os dados entraram como dígitos hexadecimais (não uma cadeia de caracteres) e são exibidos como dígitos hexadecimais, de modo que parecem inalterados.
Na verdade, se o objetivo era armazenar a cadeia de dois caracteres “AB”, então o código estava errado. O código apropriado usaria a função HEX_ENCODE
para converter a cadeia de caracteres em uma sequência de dígitos hexadecimais (ou usaria outra função de codificação para converter em outro formato, como base64) antes de armazenar os dados. Exemplos disso estão abaixo.
Exemplo de formato hexadecimal (“HEX“)¶
Uma maneira de inserir dados BINARY é codificá-los como uma sequência de caracteres hexadecimais. Um exemplo está abaixo.
Comece criando uma tabela com uma coluna BINARY:
CREATE TABLE demo_binary (b BINARY);Se você tentar inserir uma cadeia de caracteres “comum” usando a função TO_BINARY() para tentar convertê-la em um valor BINARY válido, ela falha:
INSERT INTO demo_binary (b) SELECT TO_BINARY('HELP', 'HEX');Aqui está a mensagem de erro:
100115 (22000): The following string is not a legal hex-encoded value: 'HELP'Desta vez, converta explicitamente a entrada em uma sequência de dígitos hexadecimais antes de inseri-la (isto será bem sucedido):
INSERT INTO demo_binary (b) SELECT TO_BINARY(HEX_ENCODE('HELP'), 'HEX');Agora, recupere os dados:
SELECT TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary; +---------------+----------------------------------+ | TO_VARCHAR(B) | HEX_DECODE_STRING(TO_VARCHAR(B)) | |---------------+----------------------------------| | 48454C50 | HELP | +---------------+----------------------------------+
Como você pode ver, por padrão a saída é mostrada como hexadecimal. Para recuperar a cadeia de caracteres original, use a função HEX_DECODE_STRING
(o complemento da função HEX_ENCODE_STRING
que foi usada anteriormente para codificar a cadeia de caracteres).
O que se segue ajuda a mostrar com mais detalhes o que está acontecendo internamente:
SELECT 'HELP', HEX_ENCODE('HELP'), b, HEX_DECODE_STRING(HEX_ENCODE('HELP')), TO_VARCHAR(b), HEX_DECODE_STRING(TO_VARCHAR(b)) FROM demo_binary;
Saída:
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 | +--------+--------------------+----------+---------------------------------------+---------------+----------------------------------+
Exemplo de formato BASE64¶
Antes de ler esta seção, leia a seção sobre o formato hexadecimal acima. Os conceitos básicos são semelhantes, e a seção sobre o formato hexadecimal os explica com mais detalhes.
Comece criando uma tabela com uma coluna BINARY:
CREATE TABLE demo_binary (b BINARY);Insira uma linha:
INSERT INTO demo_binary (b) SELECT TO_BINARY(BASE64_ENCODE('HELP'), 'BASE64');Recupere essa linha:
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 | +--------+-----------------------+---------------------------------------------+-------------------------+-----------------------------------------------+
Exemplo de formato UTF-8¶
Comece criando uma tabela com uma coluna BINARY:
CREATE TABLE demo_binary (b BINARY);Insira uma linha:
INSERT INTO demo_binary (b) SELECT TO_BINARY('HELP', 'UTF-8');Recupere essa linha:
SELECT 'HELP', TO_VARCHAR(b, 'UTF-8') FROM demo_binary; +--------+------------------------+ | 'HELP' | TO_VARCHAR(B, 'UTF-8') | |--------+------------------------| | HELP | HELP | +--------+------------------------+