Introdução às tabelas híbridas

Introdução

Uma tabela híbrida é um tipo de tabela Snowflake otimizada para cargas de trabalho transacionais e analíticas híbridas. Essas cargas de trabalho exigem baixa latência e alto rendimento em leituras e gravações pequenas, porém aleatórias, que geralmente acessam uma única linha em uma tabela. Tabelas híbridas impõem restrições de integridade exclusivas e referenciais, que são essenciais para cargas de trabalho transacionais.

Você pode usar uma tabela híbrida junto com outras tabelas e recursos do Snowflake para alimentar cargas de trabalho do Unistore, que unem dados transacionais e analíticos em uma única plataforma.

As tabelas híbridas são perfeitamente integradas à arquitetura Snowflake existente. Os clientes se conectam ao mesmo serviço de banco de dados Snowflake. As consultas são compiladas e otimizadas na camada de serviços de nuvem e executadas no mesmo mecanismo de consulta em warehouses virtuais. Essa arquitetura oferece vários benefícios-chave:

  • Os recursos da plataforma Snowflake, como governança de dados, funcionam com tabelas híbridas prontas para uso.

  • Você pode executar cargas de trabalho híbridas que combinam consultas operacionais e analíticas.

  • Você pode unir tabelas híbridas com outras tabelas Snowflake, e a consulta será executada de forma nativa e eficiente no mesmo mecanismo de consulta. Nenhuma federação é necessária.

  • Você pode executar uma transação atômica em tabelas híbridas e outras tabelas Snowflake. Não há necessidade de orquestrar sua própria confirmação em duas fases.

Arquitetura Unistore

As tabelas híbridas utilizam um armazenamento de linhas como armazenamento de dados primário para fornecer excelente desempenho de consulta operacional. Quando você grava em uma tabela híbrida, os dados são gravados diretamente no armazenamento de linhas. Os dados são copiados de forma assíncrona para o armazenamento de objetos a fim de fornecer melhor desempenho e isolamento de carga de trabalho para grandes verificações, sem afetar as cargas de trabalho operacionais em andamento. Alguns dados também podem ser armazenados em cache em formato colunar no seu warehouse para fornecer melhor desempenho em consultas analíticas. Você simplesmente executa instruções SQL na tabela híbrida lógica e o otimizador de consulta decide de onde ler os dados para fornecer o melhor desempenho. Você obtém uma exibição consistente dos seus dados sem precisar se preocupar com a infraestrutura subjacente.

O que você aprenderá

Neste tutorial você aprenderá a:

  • Crie e carregue em massa tabelas híbridas.

  • Crie e verifique a aplicação de restrições UNIQUE, PRIMARY KEY e FOREIGN KEY.

  • Execute atualizações simultâneas que dependem de bloqueios em nível de linha.

  • Execute uma operação de múltiplas instruções em uma transação atômica consistente (em tabelas híbridas e padrão).

  • Consulte tabelas híbridas e junte-as a tabelas padrão.

  • Verifique se os princípios de segurança e governança se aplicam às tabelas híbridas e padrão.

Pré-requisitos

Este tutorial pressupõe que você:

Etapa 1. Configurar sua conta

Para começar, configure sua conta Snowflake criando uma nova planilha, uma função, objetos de banco de dados e um warehouse virtual. Depois, você poderá criar duas tabelas híbridas e uma tabela padrão. Siga estes passos:

  1. Em Worksheets, clique no botão + no canto superior direito de Snowsight e selecione SQL Worksheet.

  2. Renomeie a planilha selecionando o nome do carimbo de data/hora gerado automaticamente e digitando Hybrid Tables - QuickStart.

  3. Conclua as etapas a seguir copiando o bloco de comandos SQL para sua planilha e executando todos eles.

    1. Use a função ACCOUNTADMIN para criar a função personalizada hybrid_quickstart_role e, em seguida, conceda essa função ao usuário atual.

    2. Crie o warehouse hybrid_quickstart_wh e o banco de dados hybrid_quickstart_db. Conceda a propriedade desses objetos à nova função.

    3. Use a nova função para criar o esquema data.

    4. Use o novo warehouse. (O banco de dados e o esquema que você criou já estão em uso, por padrão.)

    USE ROLE ACCOUNTADMIN;
    CREATE OR REPLACE ROLE hybrid_quickstart_role;
    SET my_user = CURRENT_USER();
    GRANT ROLE hybrid_quickstart_role TO USER IDENTIFIER($my_user);
    
    CREATE OR REPLACE WAREHOUSE hybrid_quickstart_wh WAREHOUSE_SIZE = XSMALL, AUTO_SUSPEND = 300, AUTO_RESUME = TRUE;
    GRANT OWNERSHIP ON WAREHOUSE hybrid_quickstart_wh TO ROLE hybrid_quickstart_role;
    CREATE OR REPLACE DATABASE hybrid_quickstart_db;
    GRANT OWNERSHIP ON DATABASE hybrid_quickstart_db TO ROLE hybrid_quickstart_role;
    
    USE ROLE hybrid_quickstart_role;
    CREATE OR REPLACE SCHEMA data;
    
    USE WAREHOUSE hybrid_quickstart_wh;
    
    Copy

Etapa 2. Criar e carregar em massa três tabelas

Este tutorial usa a empresa fictícia de food truck Tasty Bytes Snowflake para simular um caso de uso em que você pode fornecer dados para um aplicativo.

Você criará três tabelas:

  • Tabela híbrida order_header - Esta tabela armazena metadados de pedidos, como truck_id, customer_id, order_amount e assim por diante.

  • Tabela híbrida truck - Esta tabela armazena metadados do food truck, como truck_id, franchise_id, menu_type_id e assim por diante.

  • Tabela padrão truck_history - Esta tabela armazena informações históricas sobre food trucks, permitindo que você acompanhe as alterações ao longo do tempo.

Você está criando tabelas híbridas e padrão para demonstrar quão bem elas funcionam juntas. No entanto, as tabelas híbridas têm algumas diferenças fundamentais em sua definição e comportamento:

  • Tabelas híbridas requerem uma chave primária em uma ou mais colunas (o que implica a criação de um índice de chave primária).

  • Tabelas híbridas permitem a criação de índices secundários em qualquer coluna.

  • As restrições PRIMARY KEY, FOREIGN KEY e UNIQUE são todas aplicadas em tabelas híbridas.

  • Os bloqueios em tabelas híbridas são no nível da linha, não no nível da tabela.

  • Os dados da tabela híbrida residem em um armazenamento de linha, mas também são copiados para o armazenamento de objeto em colunas.

Essas diferenças resultam em:

  • Suporte para integridade referencial quando dados de tabela são carregados, atualizados ou excluídos.

  • Operações DML mais rápidas (especialmente aquelas que atualizam linhas únicas).

  • Consultas de pesquisa mais rápidas.

Você pode carregar dados em massa em tabelas híbridas copiando dados de um estágio ou de outras tabelas (ou seja, usando CTAS,, COPY INTO <tabela> ou INSERT INTO … SELECT). O carregamento de dados em massa em uma tabela híbrida usando uma instrução CTAS é altamente recomendado porque há várias otimizações que só podem ser aplicadas quando os dados são carregados como parte da criação da tabela.

Crie um formato de arquivo, que descreve um conjunto de dados preparados que você pode acessar ou carregar em tabelas do Snowflake, e um estágio, que é um objeto do Snowflake que aponta para um local de armazenamento em nuvem que o Snowflake pode acessar para ingerir e consultar dados. Os dados são armazenados em um bucket S3 AWS de acesso público que você referencia ao criar o estágio.

CREATE OR REPLACE FILE FORMAT csv_format TYPE = CSV FIELD_DELIMITER = ',' SKIP_HEADER = 1 NULL_IF = ('NULL', 'null') EMPTY_FIELD_AS_NULL = true;
CREATE OR REPLACE STAGE frostbyte_tasty_bytes_stage URL = 's3://sfquickstarts/hybrid_table_guide' FILE_FORMAT = csv_format;
Copy

Agora use a instrução LIST para retornar todos os arquivos no FROSTBYTE_TASTY_BYTES_STAGE:

LIST @frostbyte_tasty_bytes_stage;
Copy

A instrução deve retornar dois registros: um para o arquivo TRUCK.csv e outro para o arquivo ORDER_HEADER.csv.

Saída do comando LIST, com nomes e tamanhos de dois arquivos.

Depois de criar o estágio, que aponta para o local dos dados no armazenamento em nuvem, você pode criar e carregar os dados no truck usando um comando CTAS que seleciona dados do arquivo TRUCK.csv. Observe a restrição PRIMARY KEY na coluna truck_id.

A segunda instrução DDL cria uma tabela padrão chamada truck_history, também usando uma instrução CTAS.

SET CURRENT_TIMESTAMP = CURRENT_TIMESTAMP();

CREATE OR REPLACE HYBRID TABLE truck (
  truck_id NUMBER(38,0) NOT NULL,
  menu_type_id NUMBER(38,0),
  primary_city VARCHAR(16777216),
  region VARCHAR(16777216),
  iso_region VARCHAR(16777216),
  country VARCHAR(16777216),
  iso_country_code VARCHAR(16777216),
  franchise_flag NUMBER(38,0),
  year NUMBER(38,0),
  make VARCHAR(16777216),
  model VARCHAR(16777216),
  ev_flag NUMBER(38,0),
  franchise_id NUMBER(38,0),
  truck_opening_date DATE,
  truck_email VARCHAR NOT NULL UNIQUE,
  record_start_time TIMESTAMP,
  PRIMARY KEY (truck_id)
  )
  AS
  SELECT
      t.$1 AS truck_id,
      t.$2 AS menu_type_id,
      t.$3 AS primary_city,
      t.$4 AS region,
      t.$5 AS iso_region,
      t.$6 AS country,
      t.$7 AS iso_country_code,
      t.$8 AS franchise_flag,
      t.$9 AS year,
      t.$10 AS make,
      t.$11 AS model,
      t.$12 AS ev_flag,
      t.$13 AS franchise_id,
      t.$14 AS truck_opening_date,
      CONCAT(truck_id, '_truck@email.com') truck_email,
      $CURRENT_TIMESTAMP AS record_start_time
    FROM @FROSTBYTE_TASTY_BYTES_STAGE (PATTERN=>'.*TRUCK.csv') t;

CREATE OR REPLACE TABLE truck_history (
  truck_id NUMBER(38,0) NOT NULL,
  menu_type_id NUMBER(38,0),
  primary_city VARCHAR(16777216),
  region VARCHAR(16777216),
  iso_region VARCHAR(16777216),
  country VARCHAR(16777216),
  iso_country_code VARCHAR(16777216),
  franchise_flag NUMBER(38,0),
  year NUMBER(38,0),
  make VARCHAR(16777216),
  model VARCHAR(16777216),
  ev_flag NUMBER(38,0),
  franchise_id NUMBER(38,0),
  truck_opening_date DATE,
  truck_email VARCHAR NOT NULL UNIQUE,
  record_start_time TIMESTAMP,
  record_end_time TIMESTAMP,
  PRIMARY KEY (truck_id)
  )
  AS
  SELECT
      t.$1 AS truck_id,
      t.$2 AS menu_type_id,
      t.$3 AS primary_city,
      t.$4 AS region,
      t.$5 AS iso_region,
      t.$6 AS country,
      t.$7 AS iso_country_code,
      t.$8 AS franchise_flag,
      t.$9 AS year,
      t.$10 AS make,
      t.$11 AS model,
      t.$12 AS ev_flag,
      t.$13 AS franchise_id,
      t.$14 AS truck_opening_date,
      CONCAT(truck_id, '_truck@email.com') truck_email,
      $CURRENT_TIMESTAMP AS record_start_time,
      NULL AS record_end_time
   FROM @frostbyte_tasty_bytes_stage (PATTERN=>'.*TRUCK.csv') t;
Copy

A instrução DDL a seguir cria a estrutura para a tabela híbrida order_header. Observe a restrição PRIMARY KEY na coluna order_id, a restrição FOREIGN KEY na coluna truck_id da tabela truck e o índice secundário na coluna order_ts.

CREATE OR REPLACE HYBRID TABLE order_header (
  order_id NUMBER(38,0) NOT NULL,
  truck_id NUMBER(38,0),
  location_id NUMBER(19,0),
  customer_id NUMBER(38,0),
  discount_id FLOAT,
  shift_id NUMBER(38,0),
  shift_start_time TIME(9),
  shift_end_time TIME(9),
  order_channel VARCHAR(16777216),
  order_ts TIMESTAMP_NTZ(9),
  served_ts VARCHAR(16777216),
  order_currency VARCHAR(3),
  order_amount NUMBER(38,4),
  order_tax_amount VARCHAR(16777216),
  order_discount_amount VARCHAR(16777216),
  order_total NUMBER(38,4),
  order_status VARCHAR(16777216) DEFAULT 'INQUEUE',
  PRIMARY KEY (order_id),
  FOREIGN KEY (truck_id) REFERENCES TRUCK(truck_id),
  INDEX IDX01_ORDER_TS(order_ts)
);
Copy

A instrução DML a seguir insere dados na tabela order_header, usando uma instrução INSERT INTO … SELECT.

INSERT INTO order_header (
  order_id,
  truck_id,
  location_id,
  customer_id,
  discount_id,
  shift_id,
  shift_start_time,
  shift_end_time,
  order_channel,
  order_ts,
  served_ts,
  order_currency,
  order_amount,
  order_tax_amount,
  order_discount_amount,
  order_total,
  order_status)
  SELECT
      t.$1 AS order_id,
      t.$2 AS truck_id,
      t.$3 AS location_id,
      t.$4 AS customer_id,
      t.$5 AS discount_id,
      t.$6 AS shift_id,
      t.$7 AS shift_start_time,
      t.$8 AS shift_end_time,
      t.$9 AS order_channel,
      t.$10 AS order_ts,
      t.$11 AS served_ts,
      t.$12 AS order_currency,
      t.$13 AS order_amount,
      t.$14 AS order_tax_amount,
      t.$15 AS order_discount_amount,
      t.$16 AS order_total,
      '' as order_status
    FROM @frostbyte_tasty_bytes_stage (PATTERN=>'.*ORDER_HEADER.csv') t;
Copy

Etapa 3. Explorar seus dados

Anteriormente você criou a função hybrid_quickstart_role, o warehouse hybrid_quickstart_wh, o banco de dados hybrid_quickstart_db e o esquema data. Continue a usar esses objetos.

Você também criou e carregou as tabelas truck, truck_history e order_header. Agora você pode executar algumas consultas e se familiarizar com os dados nessas tabelas e seus metadados.

Use o comando SHOW TABLES para exibir propriedades e metadados de tabelas padrão e híbridas. Use o comando SHOW HYBRID TABLES para exibir informações somente sobre tabelas híbridas.

SHOW TABLES LIKE '%truck%';
Copy
Saída do comando SHOW TABLES para a tabela do food truck
SHOW HYBRID TABLES LIKE '%order_header%';
Copy
Saída do comando SHOW HYBRID TABLES para a tabela order_header

Exiba informações sobre as colunas na tabela usando comandos DESCRIBE <objeto>. Observe as colunas com restrições PRIMARY KEY e UNIQUE.

DESCRIBE TABLE truck;
Copy
Saída do comando DESCRIBE para a tabela do food truck
DESCRIBE TABLE order_header;
Copy
Saída do comando DESCRIBE para a tabela order_header

Liste as tabelas híbridas para as quais você tem privilégios de acesso.

SHOW HYBRID TABLES;
Copy
Saída do comando SHOW HYBRIDTABLES

Liste todos os índices para os quais você tem privilégios de acesso. Anote o valor na coluna is_unique para cada índice.

SHOW INDEXES;
Copy
Saída do comando SHOW INDEXES

Veja dados de amostra das tabelas executando estas consultas simples.

SELECT * FROM truck LIMIT 10;
SELECT * FROM truck_history LIMIT 10;
SELECT * FROM order_header LIMIT 10;
Copy

A saída da primeira consulta é semelhante à seguinte:

Saída da consulta SELECT em relação à tabela do food truck

Etapa 4. Teste o comportamento das restrições UNIQUE e FOREIGN KEY

Nesta etapa, você testará as restrições UNIQUE e FOREIGN KEY. Essas restrições são aplicadas quando definidas em tabelas híbridas.

Restrições UNIQUE preservam a integridade dos dados evitando que valores duplicados sejam inseridos em uma coluna. Restrições FOREIGN KEY funcionam em conjunto com restrições PRIMARY KEY para preservar a integridade referencial. Um valor não pode ser inserido em uma coluna de chave primária se nenhum valor de chave estrangeira correspondente existir na tabela de referência. Por exemplo, uma venda de um produto com ID 100 não pode ser registrada em uma tabela de fatos de vendas se tal ID de produto ainda não existir em uma tabela de dimensões de produto referenciada.

Ambos os tipos de restrições oferecem suporte à precisão e à consistência dos dados para aplicativos que dependem fortemente de um processamento de transação confiável, mas rápido.

Etapa 4.1. Testar uma restrição UNIQUE

Uma restrição UNIQUE garante que todos os valores em uma coluna sejam diferentes. Na tabela truck, você definiu a coluna truck_email como NOT NULL e UNIQUE.

Dada a restrição UNIQUE, se você tentar inserir dois registros com o mesmo endereço de e-mail, a instrução falhará. Para testar esse comportamento, execute os seguintes comandos.

Comece selecionando um endereço de e-mail existente e configurando uma variável truck_email para essa cadeia de caracteres. Em seguida, selecione o valor máximo de truck_id na tabela e defina outra variável max_truck_id para esse valor. Em seguida, defina uma terceira variável, new_truck_id que incrementa max_truck_id em 1. Esse processo garante que você não encontre o erro “Chave primária já existe” ao inserir uma nova linha.

Por fim, insira a nova linha.

SET truck_email = (SELECT truck_email FROM truck LIMIT 1);
SET max_truck_id = (SELECT MAX(truck_id) FROM truck);
SET new_truck_id = $max_truck_id+1;
INSERT INTO truck VALUES
  ($new_truck_id,2,'Stockholm','Stockholm län','Stockholm','Sweden','SE',1,2001,'Freightliner','MT45 Utilimaster',0,276,'2020-10-01',$truck_email,CURRENT_TIMESTAMP());
Copy

A instrução INSERT falha e você recebe a seguinte mensagem de erro:

Duplicate key value violates unique constraint SYS_INDEX_TRUCK_UNIQUE_TRUCK_EMAIL

Agora crie um novo endereço de e-mail exclusivo e insira um novo registro na tabela truck:

SET new_unique_email = CONCAT($new_truck_id, '_truck@email.com');
INSERT INTO truck VALUES ($new_truck_id,2,'Stockholm','Stockholm län','Stockholm','Sweden','SE',1,2001,'Freightliner','MT45 Utilimaster',0,276,'2020-10-01',$new_unique_email,CURRENT_TIMESTAMP());
Copy

A instrução INSERT deve ser executada com sucesso desta vez.

Etapa 4.2. Testar uma restrição FOREIGN KEY

Nesta etapa você testará uma restrição FOREIGN KEY.

Primeiro, mostre o DDL que você usou para criar a tabela order_header executando a função GET_DDL. Observe a restrição FOREIGN KEY para a coluna truck_id na saída.

SELECT GET_DDL('table', 'order_header');
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

Saída de get_ddl na tabela order_header

Agora tente inserir um novo registro na tabela order_header, usando um ID de food truck inexistente.

SET max_order_id = (SELECT MAX(order_id) FROM order_header);
SET new_order_id = ($max_order_id +1);
SET no_such_truck_id = -1;
INSERT INTO order_header VALUES
  ($new_order_id,$no_such_truck_id,6090,0,0,0,'16:00:00','23:00:00','','2022-02-18 21:38:46.000','','USD',17.0000,'','',17.0000,'');
Copy

A instrução INSERT deve falhar porque viola a restrição FOREIGN KEY na tabela truck. Você deve receber a seguinte mensagem de erro:

Foreign key constraint SYS_INDEX_ORDER_HEADER_FOREIGN_KEY_TRUCK_ID_TRUCK_TRUCK_ID was violated.

Agora use a nova variável new_truck_id que você usou anteriormente e insira um novo registro na tabela order_header:

INSERT INTO order_header VALUES
  ($new_order_id,$new_truck_id,6090,0,0,0,'16:00:00','23:00:00','','2022-02-18 21:38:46.000','','USD',17.0000,'','',17.0000,'');
Copy

A instrução INSERT deve ser executada com sucesso desta vez.

Etapa 4.3. Tentar truncar uma tabela referenciada por uma restrição FOREIGN KEY

Em seguida, você pode verificar se uma tabela referenciada por uma restrição FOREIGN KEY não pode ser truncada enquanto o relacionamento de chave estrangeira existir. Execute a seguinte instrução TRUNCATE TABLE:

TRUNCATE TABLE truck;
Copy

A instrução deverá falhar e você deverá receber a seguinte mensagem de erro:

91458 (0A000): Hybrid table 'TRUCK' cannot be truncated as it is involved in active foreign key constraints.

Etapa 4.4. Excluir uma linha referenciada por uma restrição FOREIGN KEY

Em seguida, você pode verificar se um registro referenciado por uma restrição FOREIGN KEY não pode ser excluído enquanto o relacionamento de chave estrangeira existir. Execute a seguinte instrução DELETE.

DELETE FROM truck WHERE truck_id = $new_truck_id;
Copy

A instrução deverá falhar e você deverá receber a seguinte mensagem de erro:

Foreign keys that reference key values still exist.

Para excluir um registro referenciado por uma restrição FOREIGN KEY, você deve primeiro excluir o registro correspondente da tabela order_header. Então você pode excluir o registro referenciado da tabela truck. Execute as seguintes instruções DELETE:

DELETE FROM order_header WHERE order_id = $new_order_id;
DELETE FROM truck WHERE truck_id = $new_truck_id;
Copy

Ambas as instruções devem ser executadas com sucesso.

Etapa 5. Use o bloqueio em nível de linha para executar atualizações simultâneas

Ao contrário das tabelas padrão, que usam bloqueio em nível de partição ou de tabela, as tabelas híbridas empregam bloqueio em nível de linha para operações de atualização. O bloqueio em nível de linha permite atualizações simultâneas em registros independentes para que as transações não esperem por bloqueios de tabela completos. Para aplicativos que dependem de cargas de trabalho transacionais pesadas, os tempos de espera para bloqueios devem ser reduzidos ao mínimo, permitindo que operações simultâneas acessem a mesma tabela com muita frequência.

Nesta etapa, você pode testar atualizações simultâneas em diferentes registros na tabela híbrida order_header.

Você usará a planilha principal Hybrid Tables - QuickStart que criou anteriormente e criará uma nova planilha chamada Hybrid Tables - QuickStart Session 2 para simular uma nova sessão. Na planilha Hybrid Tables - QuickStart, você iniciará uma nova transação usando a instrução BEGIN e, em seguida, executará uma instrução UPDATE (uma operação DML). Antes de executar a instrução de transação COMMIT, você abrirá a planilha Hybrid Tables - QuickStart Session 2 e executará outra instrução UPDATE. Por fim, você confirmará a transação aberta.

Etapa 5.1. Criar uma nova planilha

Em Worksheets, clique no botão + no canto superior direito de Snowsight e selecione SQL Worksheet.

Renomeie a planilha selecionando o nome do carimbo de data/hora gerado automaticamente e digitando Hybrid Tables - QuickStart Session 2. Essa nova planilha será usada somente na etapa atual.

Etapa 5.2. Executar atualizações simultâneas

Primeiro, abra a planilha Hybrid Tables - QuickStart. Certifique-se de que está usando a função, o warehouse, o banco de dados e o esquema corretos e, em seguida, defina e selecione a variável max_order_id.

USE ROLE hybrid_quickstart_role;
USE WAREHOUSE hybrid_quickstart_wh;
USE DATABASE hybrid_quickstart_db;
USE SCHEMA data;

SET max_order_id = (SELECT MAX(order_id) FROM order_header);
SELECT $max_order_id;
Copy

Observe o valor da variável max_order_id.

Inicie uma nova transação e execute a primeira instrução UPDATE.

BEGIN;
UPDATE order_header
  SET order_status = 'COMPLETED'
  WHERE order_id = $max_order_id;
Copy

Observe que você não confirmou a transação, então agora há um bloqueio aberto na linha que corresponde a essa condição:

WHERE order_id = $max_order_id
Copy

Execute o comando SHOW TRANSACTIONS, que deve retornar uma única transação aberta.

SHOW TRANSACTIONS;
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

Saída do comando SHOW TRANSACTIONS, mostrando uma transação aberta

Abra a planilha Hybrid Tables - QuickStart Session 2. Certifique-se de que está usando a função, o warehouse, o banco de dados e o esquema corretos e, em seguida, defina e selecione a variável min_order_id.

USE ROLE hybrid_quickstart_role;
USE WAREHOUSE hybrid_quickstart_wh;
USE DATABASE hybrid_quickstart_db;
USE SCHEMA data;
Copy
SET min_order_id = (SELECT MIN(order_id) FROM order_header);
SELECT $min_order_id;
Copy

Observe que o valor min_order_id é diferente do valor max_order_id que você usou na primeira instrução UPDATE. Execute a segunda instrução UPDATE.

UPDATE order_header
  SET order_status = 'COMPLETED'
  WHERE order_id = $min_order_id;
Copy

Como as tabelas híbridas usam bloqueio em nível de linha e a transação aberta bloqueia a linha WHERE order_id = $MAX_ORDER_ID, a instrução UPDATE é executada com sucesso.

Abra a planilha Hybrid Tables - QuickStart e confirme a transação aberta.

COMMIT;
Copy

Execute a seguinte consulta para exibir os registros atualizados:

SELECT * FROM order_header WHERE order_status = 'COMPLETED';
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

O resultado SELECT da tabela order_header onde order_status está concluído

Etapa 6. Demonstrar consistência

Nesta etapa, você aprenderá sobre um recurso exclusivo das tabelas híbridas: a capacidade de executar operações com múltiplas instruções de forma nativa, fácil e eficaz em uma transação atômica consistente, com acesso a tabelas híbridas e tabelas padrão. As transações Snowflake garantem as propriedades “ACID” de atomicidade, consistência, isolamento e durabilidade. Qualquer transação é tratada como uma unidade atômica; preserva um estado consistente do banco de dados quando ocorrem gravações; é isolada de outras transações simultâneas (como se estivessem sendo executadas sequencialmente); e é confirmada de forma duradoura (permanece confirmada, uma vez confirmada).

Neste exemplo, a empresa adquire um food truck novo do mesmo modelo de um food truck existente. Consequentemente, você deve atualizar a coluna year do registro relevante na tabela híbrida truck para refletir a alteração. Após essa atualização, você precisa atualizar imediatamente uma linha e inserir uma nova linha na tabela truck_history. Essa tabela padrão rastreará e preservará todas as alterações na frota de food trucks ao longo do tempo. Você conclui todas essas etapas como parte de uma transação explicitamente confirmada.

Etapa 6.1. Executar uma única transação que contenha várias instruções DML

Abra a planilha Hybrid Tables - QuickStart original.

Inicie uma nova transação para garantir que uma série subsequente de operações seja tratada como uma única unidade atômica. Em seguida, execute várias instruções DML:

  • Atualize o registro do food truck relevante na tabela híbrida truck.

  • Atualize o registro correspondente na tabela truck_history configurando o record_end_time para marcar o fim de sua validade.

  • Insira um novo registro na tabela truck_history, capturando as informações atualizadas.

Por fim, confirme a transação.

BEGIN;
SET CURRENT_TIMESTAMP = CURRENT_TIMESTAMP();
UPDATE truck SET year = '2024', record_start_time=$CURRENT_TIMESTAMP WHERE truck_id = 1;
UPDATE truck_history SET record_end_time=$CURRENT_TIMESTAMP WHERE truck_id = 1 AND record_end_time IS NULL;
INSERT INTO truck_history SELECT *, NULL AS record_end_time FROM truck WHERE truck_id = 1;
COMMIT;
Copy

Etapa 6.2. Verificar os resultados

Agora execute as seguintes consultas SELECT para revisar os resultados das instruções UPDATE e INSERT.

A primeira consulta deve retornar duas linhas, e a segunda consulta deve retornar uma.

SELECT * FROM truck_history WHERE truck_id = 1;
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

Saída da consulta truck_history que retorna duas linhas
SELECT * FROM truck WHERE truck_id = 1;
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

Saída da consulta de food trucks que retorna uma linha

Etapa 7. Juntar uma tabela híbrida a uma tabela padrão

Nesta etapa, você executa uma consulta de junção que combina dados de uma tabela híbrida (order_header) e uma tabela padrão (truck_history). Esta consulta demonstra a interoperabilidade dos dois tipos de tabela.

Etapa 7.1. Explorar os dados nas tabelas

Anteriormente você criou e carregou a tabela order_header. Agora você pode executar algumas consultas e revisar algumas informações para se familiarizar com a tabela. Primeiro, liste as tabelas no banco de dados com o comando SHOW TABLES e, em seguida, selecione duas colunas da saída dessa lista.

SHOW TABLES IN DATABASE hybrid_quickstart_db;
SELECT "name", "is_hybrid" FROM TABLE(RESULT_SCAN(last_query_id()));
Copy

A saída deste comando é semelhante ao seguinte resultado parcial:

Consulta que mostra se as tabelas são híbridas

Agora execute duas consultas simples:

SELECT * FROM truck_history LIMIT 10;
SELECT * FROM order_header LIMIT 10;
Copy

A saída da segunda consulta é semelhante ao seguinte resultado parcial:

Consulta que retorna 10 linhas da tabela order_header

Etapa 7.2. Juntar uma tabela híbrida a uma tabela padrão

Para juntar a tabela híbrida order_header com a tabela padrão truck_history, execute a seguinte instrução SET e consulta. Juntar tabelas híbridas a tabelas padrão não requer nenhuma sintaxe especial.

SET order_id = (SELECT order_id FROM order_header LIMIT 1);

SELECT hy.*,st.*
  FROM order_header AS hy JOIN truck_history AS st ON hy.truck_id = st.truck_id
  WHERE hy.order_id = $order_id
    AND st.record_end_time IS NULL;
Copy

O resultado da junção é semelhante ao seguinte resultado parcial:

Consulta que retorna os resultados de uma junção entre uma tabela híbrida e uma tabela padrão

Etapa 8. Demonstrar segurança e governança

Nesta etapa, você executará dois exemplos relacionados à segurança para demonstrar que a funcionalidade de segurança e governança do Snowflake se aplica igualmente a tabelas padrão e híbridas.

Funções e concessões de privilégios a essas funções são mecanismos padrão para reforçar a segurança quando um grande número de usuários de banco de dados tem acesso ao mesmo sistema, seja a carga de trabalho transacional, analítica ou híbrida.

Etapa 8.1. Configurar controle de acesso à tabela híbrida e gerenciamento de usuário

O controle de acesso baseado em função (RBAC) funciona da mesma forma para tabelas híbridas e tabelas padrão. Você pode gerenciar o acesso aos dados da tabela híbrida no Snowflake concedendo privilégios a algumas funções.

Primeiro, crie uma nova função hybrid_quickstart_bi_user_role. Use a função ACCOUNTADMIN para criar a nova função.

USE ROLE ACCOUNTADMIN;
CREATE ROLE hybrid_quickstart_bi_user_role;
SET my_user = CURRENT_USER();
GRANT ROLE hybrid_quickstart_bi_user_role TO USER IDENTIFIER($my_user);
Copy

Agora você pode conceder privilégios USAGE para o warehouse hybrid_quickstart_wh, banco de dados hybrid_quickstart_db e todos os seus esquemas à nova função. Use hybrid_quickstart_role para executar as instruções GRANT.

USE ROLE hybrid_quickstart_role;
GRANT USAGE ON WAREHOUSE hybrid_quickstart_wh TO ROLE hybrid_quickstart_bi_user_role;
GRANT USAGE ON DATABASE hybrid_quickstart_db TO ROLE hybrid_quickstart_bi_user_role;
GRANT USAGE ON ALL SCHEMAS IN DATABASE hybrid_quickstart_db TO hybrid_quickstart_bi_user_role;
Copy

Usando a nova função (hybrid_quickstart_bi_user_role), tente selecionar alguns dados da tabela order_header.

USE ROLE hybrid_quickstart_bi_user_role;
USE DATABASE hybrid_quickstart_db;
USE SCHEMA data;

SELECT * FROM order_header LIMIT 10;
Copy

Você não pode selecionar nenhum dado porque a função hybrid_quickstart_bi_user_role não recebeu o privilégio SELECT necessário nas tabelas. Você recebe a seguinte mensagem de erro:

Object 'ORDER_HEADER' does not exist or not authorized.

Para resolver esse problema, use a função hybrid_quickstart_role para conceder privilégios SELECT em todas as tabelas do esquema data para hybrid_quickstart_bi_user_role.

USE ROLE hybrid_quickstart_role;
GRANT SELECT ON ALL TABLES IN SCHEMA DATA TO ROLE hybrid_quickstart_bi_user_role;
Copy

Tente selecionar novamente os dados da tabela híbrida order_header.

USE ROLE hybrid_quickstart_bi_user_role;
SELECT * FROM order_header LIMIT 10;
Copy

Desta vez a consulta é bem-sucedida porque HYBRID_QUICKSTART_BI_USER_ROLE possui os privilégios apropriados em todos os níveis da hierarquia. A saída é semelhante ao seguinte resultado parcial:

Consulta que agora permite acesso ao order_header após SELECT ser concedido no esquema DATA

Etapa 8.2. Criar e implementar uma política de mascaramento

Nesta etapa, você cria uma política de mascaramento e a aplica à coluna truck_email na tabela híbrida truck usando uma instrução ALTER TABLE … ALTER COLUMN. Uma política de mascaramento é uma maneira padrão de controlar a visibilidade de dados em nível de coluna para usuários com diferentes funções e privilégios.

Nota

Para criar políticas de mascaramento, você deve usar uma conta Enterprise Edition (ou uma conta de nível superior). Se você estiver usando uma conta Standard Edition, pule esta etapa. Para obter mais informações, consulte Edições do Snowflake.

Use a função hybrid_quickstart_role e crie a nova política de mascaramento, que tem como objetivo mascarar valores de colunas inteiras de funções não autorizadas.

USE ROLE hybrid_quickstart_role;

CREATE MASKING POLICY hide_column_values AS
  (col_value VARCHAR) RETURNS VARCHAR ->
    CASE WHEN CURRENT_ROLE() IN ('HYBRID_QUICKSTART_ROLE') THEN col_value
      ELSE '***MASKED***'
      END;
Copy

Agora aplique essa política à tabela híbrida.

ALTER TABLE truck MODIFY COLUMN truck_email
  SET MASKING POLICY hide_column_values USING (truck_email);
Copy

Como você está usando o hybrid_quickstart_role, a coluna truck_email não deve ser mascarada. Execute a seguinte consulta:

SELECT * FROM truck LIMIT 10;
Copy
Consulta que não mascara a coluna truck_email

Troque para HYBRID_QUICKSTART_BI_USER_ROLE e execute a consulta novamente. A coluna TRUCK_EMAIL deve estar mascarada agora.

USE ROLE hybrid_quickstart_bi_user_role;
SELECT * FROM truck LIMIT 10;
Copy
Consulta que mascara a coluna truck_email

Etapa 9. Limpeza, conclusão e leituras adicionais

Limpeza

Para limpar seu ambiente Snowflake, execute as seguintes instruções SQL:

USE ROLE hybrid_quickstart_role;
USE WAREHOUSE hybrid_quickstart_wh;
USE DATABASE hybrid_quickstart_db;
USE SCHEMA data;
Copy
DROP DATABASE hybrid_quickstart_db;
DROP WAREHOUSE hybrid_quickstart_wh;
USE ROLE ACCOUNTADMIN;
DROP ROLE hybrid_quickstart_role;
DROP ROLE hybrid_quickstart_bi_user_role;
Copy

Por fim, exclua manualmente as planilhas Hybrid Tables - QuickStart e Hybrid Tables - QuickStart Session 2.

O que você aprendeu

Neste tutorial, você aprendeu como:

  • Crie e carregue em massa tabelas híbridas.

  • Crie e verifique a aplicação de restrições UNIQUE, PRIMARY KEY e FOREIGN KEY.

  • Execute atualizações simultâneas que dependem de bloqueios em nível de linha.

  • Execute uma operação de múltiplas instruções em uma transação atômica consistente (em tabelas híbridas e padrão).

  • Consulte tabelas híbridas e junte-as a tabelas padrão.

  • Verifique se os princípios de segurança e governança se aplicam às tabelas híbridas e padrão.