ハイブリッド・テーブルを使い始める

概要

ハイブリッドテーブル は、ハイブリッドトランザクションおよび分析ワークロード向けに最適化されたSnowflakeテーブルタイプです。これらのワークロードでは、テーブル内の1行にアクセスすることが多い、小規模ながらランダムな読み取りと書き込みで、低レイテンシと高スループットが求められます。ハイブリッドテーブルは、トランザクションワークロードにとって重要な一意の制約と参照整合性制約を適用します。

ハイブリッドテーブルを他のSnowflakeテーブルや機能と一緒に使用して、トランザクションデータと分析データを単一のプラットフォームに統合する Unistore ワークロード を実現できます。

ハイブリッドテーブルは、既存のSnowflakeアーキテクチャにシームレスに統合されます。顧客は同じSnowflakeデータベースサービスに接続します。クエリはクラウドサービスレイヤーでコンパイルおよび最適化され、仮想ウェアハウス内の同じクエリエンジンで実行されます。このアーキテクチャには、いくつかの重要な利点があります。

  • データガバナンスなどのSnowflakeプラットフォーム機能を、ハイブリッドテーブルですぐに使用できます。

  • 運用クエリと分析クエリを組み合わせたハイブリッド ワークロードを実行できます。

  • ハイブリッドテーブルを他のSnowflakeテーブルと結合でき、クエリは同じクエリエンジンでネイティブかつ効率的に実行されます。フェデレーションは必要ありません。

  • ハイブリッドテーブルと他のSnowflakeテーブル間でアトミックトランザクションを実行できます。独自の2相コミットをオーケストレーションする必要はありません。

Unistoreアーキテクチャ

ハイブリッドテーブルは、行ストアをプライマリデータストアとして活用し、優れた運用クエリパフォーマンスを提供します。ハイブリッドテーブルに書き込むと、データは行ストアに直接書き込まれます。進行中の運用ワークロードに影響を与えることなく、大規模なスキャンのパフォーマンスとワークロードの分離を向上させるために、データは非同期的にオブジェクトストレージにコピーされます。分析クエリのパフォーマンスを向上させるために、一部のデータはウェアハウスに列形式でキャッシュされる場合もあります。論理ハイブリッドテーブルに対して SQL ステートメントを実行するだけで、最適なパフォーマンスを提供するために、クエリオプティマイザーがデータの読み取り元を決定します。基盤となるインフラストラクチャを気にすることなく、データの一貫したビューを取得できます。

学習内容

このチュートリアルでは、次の方法を学習します。

  • ハイブリッドテーブルを作成して一括ロードします。

  • UNIQUE、 PRIMARY KEY、および FOREIGN KEY 制約の適用を作成し、確認します。

  • 行レベルのロックに依存する同時更新を実行します。

  • 一貫性のあるアトミックトランザクション(ハイブリッドテーブルと標準テーブル全体)で複数のステートメント操作を実行します。

  • ハイブリッドテーブルをクエリし、標準テーブルに結合します。

  • セキュリティとガバナンスの原則がハイブリッドテーブルと標準テーブルの両方に適用されることを確認します。

前提条件

このチュートリアルでは、以下のことを前提としています。

ステップ1:アカウントを設定する

開始するには、新しいワークシート、ロール、データベース オブジェクト、仮想ウェアハウスを作成して、Snowflakeアカウントを設定します。そうすると、2つのハイブリッドテーブルと1つの標準テーブルを作成できるようになります。以下のステップを実行します。

  1. Worksheets の下で、 Snowsight の右上にある + ボタンをクリックし、 SQL Worksheet を選択します。

  2. 自動生成されたタイムスタンプ名を選択し、 Hybrid Tables - QuickStart と入力してワークシートの名前を変更します。

  3. SQL コマンドのブロックをワークシートにコピーし、すべて実行して、以下の手順を完了します。

    1. ACCOUNTADMIN ロールを使用して hybrid_quickstart_role カスタムロールを作成し、このロールを現在のユーザーに付与します。

    2. hybrid_quickstart_wh ウェアハウスと hybrid_quickstart_db データベースを作成します。これらのオブジェクトの所有権を新しいロールに付与します。

    3. 新しいロールを使用して data スキーマを作成します。

    4. 新しいウェアハウスを使用します。(デフォルトでは、作成したデータベースとスキーマはすでに使用されています)。

    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

ステップ2:3つのテーブルを作成して一括ロードする

このチュートリアルでは、Tasty Bytes Snowflakeの架空のフードトラックビジネスを使用して、アプリケーションにデータを提供できるユースケースをシミュレートします。

3つのテーブルを作成します。

  • order_header ハイブリッドテーブル - このテーブルには、 truck_idcustomer_idorder_amount などの注文メタデータが格納されます。

  • truck ハイブリッド テーブル - このテーブルには、 truck_idfranchise_idmenu_type_id などのトラックのメタデータが格納されます。

  • truck_history 標準テーブル - このテーブルにはフードトラックに関する履歴情報が保存され、時間の経過に伴う変化を追跡できます。

ハイブリッドテーブルと標準テーブルを作成して、それらがどのように連携して機能するかを示します。ただし、ハイブリッドテーブルの定義と動作には、いくつかの基本的な違いがあります。

  • ハイブリッド テーブルでは、1つ以上の列に主キーが必要です(主キーインデックスの作成が必要になります)。

  • ハイブリッドテーブルでは、任意の列に セカンダリインデックス を作成できます。

  • PRIMARY KEY、 FOREIGN KEY、および UNIQUE 制約 はすべてハイブリッドテーブルに適用されます。

  • ハイブリッド テーブルのロックはテーブルレベルではなく 行レベル です。

  • ハイブリッドテーブルデータは行ストアに存在しますが、列指向オブジェクトストレージにもコピーされます。

これらの違いにより、以下が実現されます。

  • テーブルデータの読み込み、更新、または削除時の参照整合性のサポート。

  • DML 操作の高速化(特に単一行を更新する操作)。

  • 検索クエリの高速化。

ステージまたは他のテーブルからデータをコピーして(つまり、 CTASCOPY INTO <テーブル>INSERT INTO ... SELECT)、ハイブリッドテーブルにデータを一括ロードできます。テーブルの作成の一環としてデータがロードされる場合にのみ適用できる最適化がいくつかあるため、 CTAS ステートメントを使用してハイブリッド テーブルにデータを一括ロードすることを強くお勧めします。

Snowflakeテーブルにアクセスしたりロードしたりできるステージングされたデータセットを記述する ファイル形式 と、Snowflakeがデータの取り込みとクエリの両方にアクセスできるクラウド ストレージの場所を指すSnowflakeオブジェクトである ステージ を作成します。データは、ステージの作成時に参照する、パブリックにアクセス可能な AWS S3バケットに保存されます。

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

ここで、 LIST ステートメントを使用して、 FROSTBYTE_TASTY_BYTES_STAGE 内のすべてのファイルを返します。

LIST @frostbyte_tasty_bytes_stage;
Copy

このステートメントは、 TRUCK.csv ファイル用と ORDER_HEADER.csv ファイル用の2つの記録を返します。

2つのファイルの名前とサイズを含む LIST コマンドの出力。

クラウド ストレージ内のデータの場所を指すステージを作成したら、 TRUCK.csv ファイルからデータを選択する CTAS コマンド を使用して、データを作成して truck にロードできます。 truck_id 列の PRIMARY KEY 制約に注意してください。

2番目の DDL ステートメントも truck_history ステートメントを使用して、 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

以下の DDL ステートメントは、 order_header ハイブリッドテーブルの構造を作成します。 order_id 列の PRIMARY KEY 制約、 truck テーブルの truck_id 列の FOREIGN KEY 制約、 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

以下の DML ステートメントは、 INSERTINTO ... SELECT ステートメントを使用して、 order_header テーブルにデータを挿入します。

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

ステップ3。データの探索

先ほど、 hybrid_quickstart_role ロール、 hybrid_quickstart_wh ウェアハウス、 hybrid_quickstart_db データベース、および data スキーマを作成しました。それらのオブジェクトを引き続き使用します。

また、 trucktruck_historyorder_header のテーブルも作成してロードしました。これで、いくつかのクエリを実行して、これらのテーブル内のデータとそのメタデータの両方について理解できるようになります。

標準テーブルとハイブリッドテーブルの両方のプロパティとメタデータを表示するには、 SHOW TABLES コマンドを使用します。ハイブリッドテーブルに関する情報のみを表示するには、 SHOW HYBRID TABLES コマンドを使用します。

SHOW TABLES LIKE '%truck%';
Copy
トラックテーブルの SHOW TABLES コマンドの出力
SHOW HYBRID TABLES LIKE '%order_header%';
Copy
order_headerテーブルの SHOW HYBRID TABLES コマンドの出力

DESCRIBE <オブジェクト> コマンドを使用して、テーブル内の列に関する情報を表示します。PRIMARY KEY、および UNIQUE 制約のある列に注意してください。

DESCRIBE TABLE truck;
Copy
トラックテーブルの DESCRIBE コマンドの出力
DESCRIBE TABLE order_header;
Copy
order_headerテーブルの DESCRIBE コマンドの出力

アクセス権限がある ハイブリッドテーブル をリストします。

SHOW HYBRID TABLES;
Copy
SHOW HYBRID TABLES コマンドの出力

アクセス権限を持つすべての インデックス を一覧表示します。各インデックスの is_unique 列の値に注意してください。

SHOW INDEXES;
Copy
SHOWINDEXESコマンドの出力

これらの簡単なクエリを実行して、テーブルからサンプルデータを確認します。

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

最初のクエリの出力は以下のようになります。

トラックテーブルに対する SELECT クエリの出力

ステップ4。UNIQUE 、 FOREIGN KEY 制約の動作をテストします。

このステップでは、 UNIQUE と FOREIGN KEY 制約 をテストします。これらの制約は、ハイブリッドテーブルで定義されている場合に適用されます。

UNIQUE 制約は、列に重複した値が挿入されないようにすることで、データの整合性を保持します。FOREIGN KEY 制約は、 PRIMARY KEY 制約と連動して参照整合性を保持します。参照先のテーブルに一致する外部キー値が存在しない場合は、主キー列に値を挿入できません。たとえば、参照先の製品ディメンション テーブルにそのような製品 ID がまだ存在しない場合、 ID 100 を含む製品の販売は販売ファクトテーブルに記録できません。

どちらのタイプの制約も、信頼性が高く高速なトランザクション処理に大きく依存するアプリケーションのデータの正確性と一貫性をサポートします。

ステップ4.1.UNIQUE 制約をテストする

UNIQUE 制約は、列内のすべての値が異なることを保証します。 truck テーブルで、 truck_email 列を NOT NULL および UNIQUE として定義しました。

UNIQUE 制約があるため、同じメールアドレスを持つ2つの記録を挿入しようとすると、ステートメントは失敗します。この動作をテストするには、以下のコマンドを実行します。

まず、既存のメールアドレスを選択し、その文字列に変数 truck_email を設定します。そして、テーブルから truck_id の最大値を選択し、別の変数 max_truck_id をその値に設定します。次に、 max_truck_id を1ずつ増加させる3番目の変数 new_truck_id を設定します。このプロセスにより、新しい行を挿入するときに「主キーが既に存在します」というエラーが発生しなくなります。

最後に、新しい行を挿入します。

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

INSERT ステートメントが失敗し、以下のエラーメッセージが表示されます。

Duplicate key value violates unique constraint SYS_INDEX_TRUCK_UNIQUE_TRUCK_EMAIL

ここで、新しいユニークなメールアドレスを作成し、 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

今回は INSERT ステートメントが正常に実行されるはずです。

ステップ4.2.FOREIGN KEY 制約をテストする

このステップでは、 FOREIGN KEY 制約をテストします。

まず、 GET_DDL 関数を実行し、 order_header テーブルを作成するために使用した DDL を表示します。出力の truck_id 列の FOREIGN KEY 制約に注意してください。

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

このコマンドの出力は、以下の部分的な結果のようになります。

order_headerテーブルのget_ddlの出力

ここで、存在しないトラック ID を使って、 order_header テーブルに新しい記録を挿入してみます。

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

truck テーブルの FOREIGN KEY 制約に違反するため、 INSERT ステートメントは失敗するはずです。以下のエラーメッセージが表示されるはずです。

Foreign key constraint SYS_INDEX_ORDER_HEADER_FOREIGN_KEY_TRUCK_ID_TRUCK_TRUCK_ID was violated.

ここで、先ほど使用した新しい new_truck_id 変数を使用して、 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

今回は INSERT ステートメントが正常に実行されるはずです。

ステップ4.3.FOREIGN KEY 制約によって参照されるテーブルの切り捨てを試行する

次に、 FOREIGN KEY 制約によって参照されるテーブルが、外部キー関係が存在する限り切り捨てられないことを確認できます。以下の TRUNCATE TABLE ステートメントを実行します。

TRUNCATE TABLE truck;
Copy

ステートメントは失敗し、以下のエラーメッセージが表示されるはずです。

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

ステップ4.4.FOREIGN KEY 制約によって参照されている行を削除する

次に、 FOREIGN KEY 制約によって参照される記録は、外部キーリレーションシップが存在する限り削除できないことを確認できます。以下の DELETE ステートメントを実行します。

DELETE FROM truck WHERE truck_id = $new_truck_id;
Copy

ステートメントは失敗し、以下のエラーメッセージが表示されるはずです。

Foreign keys that reference key values still exist.

FOREIGN KEY 制約によって参照される記録を削除するには、まず order_header テーブルから対応する記録を削除する必要があります。その後、参照された記録を truck テーブルから削除できます。以下の DELETE ステートメントを実行します。

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

両方のステートメントが正常に実行されるはずです。

ステップ5: 行レベルロックを使用して同時更新を実行する

パーティション レベルまたはテーブル レベルのロックを使用する標準テーブルとは異なり、ハイブリッドテーブルでは更新操作に 行レベルのロック を使用します。行レベルのロックにより、独立した記録の同時更新が可能になり、トランザクションが完全なテーブルロックを待機する必要がなくなります。大量のトランザクションワークロードに依存するアプリケーションの場合、ロックの待機時間を最小限に抑えて、同時操作で同じテーブルに頻繁にアクセスできるようにする必要があります。

このステップでは、 order_header ハイブリッドテーブルの異なる記録に対する同時更新をテストできます。

先に作成したメインのワークシート(Hybrid Tables - QuickStart)を使用し、新しいセッションをシミュレートするために新しいワークシート(Hybrid Tables - QuickStart Session 2)を作成します。 Hybrid Tables - QuickStart ワークシートから、 BEGIN ステートメントを使用して新しいトランザクションを開始し、 UPDATE ステートメント(DML オペレーション)を実行します。 COMMIT トランザクションステートメントを実行する前に、 Hybrid Tables - QuickStart Session 2 ワークシートを開き、別の UPDATE ステートメントを実行します。最後に、開いているトランザクションをコミットします。

ステップ5.1.新しいワークシートを作成する

Worksheets の下で、 Snowsight の右上にある + ボタンをクリックし、 SQL Worksheet を選択します。

自動生成されたタイムスタンプ名を選択し、 Hybrid Tables - QuickStart Session 2 と入力してワークシートの名前を変更します。この新しいワークシートは現在のステップでのみ使用されます。

ステップ5.2.同時アップデートを実行する

まず、 Hybrid Tables - QuickStart ワークシートを開きます。適切なロール、ウェアハウス、データベース、スキーマを使用していることを確認してから、 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

max_order_id 変数の値に注意してください。

新しいトランザクションを開始し、最初の UPDATE ステートメントを実行します。

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

トランザクションをコミットしていないため、この条件に一致する行にオープンロックが存在することに注意してください。

WHERE order_id = $max_order_id
Copy

SHOW TRANSACTIONS コマンドを実行すると、単一のオープントランザクションが返されます。

SHOW TRANSACTIONS;
Copy

このコマンドの出力は、以下の部分的な結果のようになります。

SHOW TRANSACTIONS コマンドの出力。1つのオープントランザクションを表示

Hybrid Tables - QuickStart Session 2 ワークシートを開きます。適切なロール、ウェアハウス、データベース、スキーマを使用していることを確認してから、 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

min_order_id の値は、最初の UPDATE ステートメントで使用した max_order_id 値とは異なることに注意してください。2番目の UPDATE ステートメントを実行します。

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

ハイブリッド テーブルは行レベルのロックを使用し、オープン トランザクションが行 WHERE order_id = $MAX_ORDER_ID をロックするため、 UPDATE ステートメントは正常に実行されます。

Hybrid Tables - QuickStart ワークシートを開き、開いているトランザクションをコミットします。

COMMIT;
Copy

更新された記録を表示するには、以下のクエリを実行します。

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

このコマンドの出力は、以下の部分的な結果のようになります。

SELECT order_statusが完了したorder_headerテーブルからの結果

ステップ6: 一貫性を示す

このステップでは、ハイブリッドテーブルと標準テーブルの両方にアクセスして、1つの一貫性のあるアトミックトランザクションで複数のステートメント操作をネイティブに、簡単かつ効率的に実行する機能である、独自のハイブリッドテーブル機能について学習します。Snowflake トランザクション は、原子性、一貫性、分離、および耐久性という "ACID" 特性を保証します。任意のトランザクションはアトミックユニットとして扱われ、書き込みの発生時に一貫したデータベース状態が維持され、他の同時実行トランザクションから分離され(順番に実行されているかのように)、永続的にコミットされます(一度コミットされるとコミットされたままになります)。

この例では、会社は既存のトラックと同じモデルの新しいトラックを取得します。その結果、 truck ハイブリッドテーブルの該当記録の year 列を更新し、変更を反映させる必要があります。この更新の後、速やかに truck_history テーブルの行を更新し、新しい行を挿入する必要があります。この標準テーブルは、時間の経過に伴うトラックフリートのすべての変更を追跡し、保存します。これらすべての手順は、明示的にコミットされた1つのトランザクションの一部として完了します。

ステップ6.1.複数の DML ステートメントを含む単一のトランザクションを実行する

元の Hybrid Tables - QuickStart ワークシートを開きます。

新しいトランザクションを開始して、後続の一連の操作が単一のアトミック単位として扱われるようにします。次に、複数の DML ステートメントを実行します。

  • truck ハイブリッドテーブルの該当トラック記録を更新します。

  • record_end_time、有効期間の終了を示すように設定して、 truck_history テーブルの対応する記録を更新します。

  • 更新された情報を取得して、 truck_history テーブルに新しい記録を挿入します。

最後に、トランザクションをコミットします。

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

ステップ6.2.結果を表示する

UPDATE、 INSERT ステートメントの結果を確認するために、以下の SELECT クエリーを実行します。

最初のクエリは2行を返し、2番目のクエリは1行を返します。

SELECT * FROM truck_history WHERE truck_id = 1;
Copy

このコマンドの出力は、以下の部分的な結果のようになります。

2行を返すtruck_historyクエリの出力
SELECT * FROM truck WHERE truck_id = 1;
Copy

このコマンドの出力は、以下の部分的な結果のようになります。

1行を返すトラッククエリの出力

ステップ7。ハイブリッドテーブルを標準テーブルに結合する

このステップでは、ハイブリッドテーブル(order_header)と標準テーブル(truck_history)のデータを結合する join クエリを実行します。このクエリは、2つのテーブル・タイプの相互運用性を示しています。

ステップ7.1.テーブルのデータを表示する

先ほど、 order_header テーブルを作成してロードしました。ここで、いくつかのクエリを実行し、情報を確認してテーブルについて理解を深めることができます。まず、 SHOW TABLES コマンドでデータベース内のテーブルをリストアップし、そのリストの出力から2つのカラムを選択します。

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

このコマンドの出力は、以下の部分的な結果のようになります。

テーブルがハイブリッドかどうかを示すクエリ

ここで、2つの簡単なクエリを実行します。

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

2番目のクエリの出力は、次の部分的な結果のようになります。

order_headerテーブルから10行を返すクエリ

ステップ7.2.ハイブリッドテーブルを標準テーブルに結合する

order_header ハイブリッドテーブルを truck_history スタンダード・テーブルに結合するには、以下の SET ステートメントとクエリを実行します。ハイブリッドテーブルを標準テーブルに結合する場合、特別な構文は必要ありません。

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

結合結果は、次の部分的な結果のようになります。

ハイブリッドテーブルと標準テーブル間の結合の結果を返すクエリ

ステップ8。セキュリティとガバナンスを実証する

このステップでは、セキュリティ関連の2つの例を実行して、Snowflake のセキュリティとガバナンス の機能が標準テーブルとハイブリッドテーブルに同様に適用されることを示します。

ロールとそれらのロールへの権限の付与は、ワークロードがトランザクション、分析、またはハイブリッドのいずれであっても、多数のデータベースユーザーが同じシステムにアクセスする場合にセキュリティを強化するための標準的なメカニズムです。

ステップ8.1.ハイブリッドテーブルアクセス制御とユーザー管理を設定する

ロールベースのアクセス制御(RBAC) は、ハイブリッドテーブルでも標準テーブルでも同じように機能します。一部のロールに権限を付与することで、Snowflakeのハイブリッドテーブルデータへのアクセスを管理できます。

新しい hybrid_quickstart_bi_user_role ロールを作成します。新しいロールを作成するには、 ACCOUNTADMIN ロールを使用します。

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

これで、 hybrid_quickstart_wh ウェアハウス、 hybrid_quickstart_db データベース、およびそのすべてのスキーマに対する USAGE 権限を新しいロールに付与できます。 hybrid_quickstart_role を使用して 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

新しいロール(hybrid_quickstart_bi_user_role)を使用して、 order_header テーブルからデータをいくつか選択してみます。

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

SELECT * FROM order_header LIMIT 10;
Copy

ロール hybrid_quickstart_bi_user_role にテーブル上で必要な SELECT 権限が付与されていないため、データを選択できません。次のエラー メッセージが表示されます。

Object 'ORDER_HEADER' does not exist or not authorized.

この問題を解決するには、ロール hybrid_quickstart_role を使用して、 data スキーマ内のすべてのテーブルに対する SELECT 権限を 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

order_header ハイブリッド テーブルからデータを選択して再試行してください。

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

今回は、 HYBRID_QUICKSTART_BI_USER_ROLE が階層のすべてのレベルで適切な権限を持っているため、クエリは成功します。出力は次の部分的な結果のようになります。

DATA スキーマに SELECT が付与された後にorder_headerへのアクセスを許可するクエリ

ステップ8.2.マスキングポリシーを作成して実装する

このステップでは、 マスキングポリシー を作成し、 ALTER TABLE ... ALTER COLUMN ステートメントを使用して、 truck ハイブリッドテーブルの truck_email 列に適用します。マスキングポリシーは、さまざまなロールと権限を持つユーザーに対するデータの列レベルの可視性を制御する標準的な方法です。

注釈

マスキングポリシーを作成するには、Enterprise Editionアカウント(または上位レベルのアカウント)を使用する必要があります。Standard Editionアカウントを使用している場合は、この手順をスキップしてください。詳細については、 Snowflake Edition をご参照ください。

hybrid_quickstart_role ロールを使用して、権限のないロールから列の値全体をマスクすることを目的とした新しいマスキングポリシーを作成します。

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

次に、このポリシーをハイブリッドテーブルに適用します。

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

現在、 hybrid_quickstart_role を使用しているため、 truck_email 列はマスクされ ません。以下のクエリを実行します。

SELECT * FROM truck LIMIT 10;
Copy
truck_email列をマスクしないクエリ

HYBRID_QUICKSTART_BI_USER_ROLE に切り替えてクエリを再度実行します。 TRUCK_EMAIL 列がマスクされるはずです。

USE ROLE hybrid_quickstart_bi_user_role;
SELECT * FROM truck LIMIT 10;
Copy
truck_emailカラムをマスクするクエリ

ステップ9。クリーンアップ、結論、追加資料

クリーンアップ

Snowflake環境をクリーンアップするには、以下の 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

最後に、 Hybrid Tables - QuickStart および Hybrid Tables - QuickStart Session 2 ワークシートを手動で削除します。

学習した内容

このチュートリアルでは、次の方法について学習しました。

  • ハイブリッドテーブルを作成して一括ロードします。

  • UNIQUE、 PRIMARY KEY、および FOREIGN KEY 制約の適用を作成し、確認します。

  • 行レベルのロックに依存する同時更新を実行します。

  • 一貫性のあるアトミックトランザクション(ハイブリッドテーブルと標準テーブル全体)で複数のステートメント操作を実行します。

  • ハイブリッドテーブルをクエリし、標準テーブルに結合します。

  • セキュリティとガバナンスの原則がハイブリッドテーブルと標準テーブルの両方に適用されることを確認します。