- 0 -
Future Tech Night
Google Cloud データ活用勉強会
2022/9/22
Shota Miyazaki
- 1 -
Profile
Name: 宮崎 将太
In: Technology Innovation Group (TIG) / DX Unit
Post: Architect
Specialty: Server Side
Like: Data Modeling, Dev Design, Beer🍺
Career:
小売
ポータル
サイト
ガス基幹
システム
大手小売
基幹
システム
小田急
IDプラット
フォーム
大手鉄道
ToC
サービス
某安否
サービス
大手企業
データ
基盤
The Go gopher was designed by Renée French
- 2 -
データ基盤 アーキテクチャ
Cloud Composer
Cloud DataFusion
BigQeury
External System
SFTP
HTTPS
Workflow management
DataPipline
DWH
call
data load
exec SQL
- 3 -
データ基盤 アーキテクチャ
Cloud Composer
Cloud DataFusion
BigQeury
External System
SFTP
HTTPS
Workflow management
DataPipline
DWH
call
data load
exec SQL
- 4 -
本日お話しすること
Design Test
Implem
ents
BigQeury
- 5 -
Design
- 6 -
BigQueryは列指向データベース Design
Product Quantity Warehaouse
dryer 30 Warehouse 2
microwave 20 Warehouse 1
dishwasher 10 null
… … …
Product
dryer
microwave
dishwasher
…
Quantity
30
20
10
…
Warehaouse
Warehouse 2
Warehouse 1
null
…
列指向データベース
行指向データベース
 RDBは行指向データベース
 行ごとにデータが格納される。
 レコードを効率的に探索できるが、レコードアクセスのた
びに全フィールドを読み取ってしまうため、大量レコード
の分析では効率が低下してしまう。
 DWHの多くは列指向データベース。BQもこちら。
 列ごとにデータが格納される。
 列を指定した大量レコード分析で高パフォーマンスを
発揮する。
 行の全フィールドを読み出そうとするとパフォーマンスが
低下してしまうので、select * は厳禁。
- 7 -
BQテーブル設計の基本は非正規化
 テーブル同士を結合してデータ抽出するより、単一テーブルに対してデータ抽出を行う方がパフォーマンスが良い
 粒度が異なるテーブルを非正規化する場合は、ARRAY型やSTRUCT型を利用して非正規化
 ただし、ARRAYやSTRUCTを使いすぎるとデータ準備がとても大変…。使用は最小限に。
Design
ID 合計金額
1 1,100
2 500
BQでの設計
RDBでのテーブル設計
注文ID 商品 単価 数量
1 商品A 100 3
1 商品B 200 4
2 商品A 100 2
2 商品C 300 1
注文ID 合計金額 注文明細
注文ID 商品 単価 数量
1 1,100 1 商品A 100 3
1 商品B 200 4
2 500 2 商品A 100 2
2 商品C 300 1
注文 注文明細 注文
Select
注文.合計金額
, 注文明細.商品
…
From
注文
Inner join ← 正規化テーブルを結合して抽出
注文明細
On 注文.ID = 注文明細.注文ID
Select
注文.合計金額
, 注文.注文明細
From
注文 ← 単一テーブルのみへアクセス
粒度ごとにテーブルを正規化
する 注文明細をARRAY<STRUCT>型
として定義する。
- 8 -
非正規化項目へのアクセス
 ARRAY項目へのアクセスにはUNNEST関数を使用する。
 ただし、UNNESTは曲者(後述)
Design
注文ID 合計金額 注文明細
注文ID 商品 単価 数量
1 1,100 1 商品A 100 3
1 商品B 200 4
2 500 2 商品A 100 2
2 商品C 300 1
Select
注文.合計金額
, 注文.注文明細
From
注文
注文ID 合計金額 注文明細
注文ID 商品 単価 数量
1 1,100 1 商品A 100 3
1 1,100 1 商品B 200 4
2 500 2 商品A 100 2
2 500 2 商品C 300 1
select
注文.合計金額
, 注文明細.注文ID
, 注文明細.商品
, 注文明細.単価
from
注文
, unnest(注文明細) as 注文明細
何もしないと2行取れる換算になる。
注文明細の各フィールドにはアクセスでき
ない。
UNNESTするとARRAYが展開されて4行
取れる。
注文明細の各フィールドにはアクセ
スできる用になる。
- 9 -
パーティショニング
 Bigqueryでは大まかに3つの方法でパーティショニングが可能。
 特に制約がなければ列パーティショニング使用がおすすめ。
Design
列パーティ
ショニング
テーブル
シャーディ
ング
取り込み時間
パーティショ
ニング
 パーティションカラムを指定して日別、
時間別、月別、年別、もしくは指定
した整数範囲でパーティショニングす
る方式。
 RDBを使用していると最も直感的な
パターン。
 特に制約がなければ列パーティショニ
ング使用がベター。
 取り込み時間で自動的にパーティシ
ョンを作成する方式。
 _PARTITIONTIMEという疑似列
が作成され、パーティションキーとして
採用される。
 時間がUTCとなってしまうため、列パ
ーティショニングとするのがおすすめ。
 [PREFIX]_YYYYMMDD などの
名前の接頭辞を使用して複数のテ
ーブルにデータを格納する方式。
 パーティショニングというよりもテーブル
分割なので、列パーティショニングや
取り込み時間パーティショニングの方
がパフォーマンス高。
 GoogleAnalyticsのBQ連携を実施す
ると自動的にこの方式になる。
- 10 -
パーティショニング etc
 DDLで有効期限を設定可能。
 指定した有効期限を超過した場合、自動的に過去パーティションが削除される。
 有効期限の境界はUTCとなってしまうことに注意。
 有効期限はALTER TABLEで後から変更することも可能なので、リリース後安定期に入ってから改廃を開始する運用も容易。
Design
 パーティションフィルタ
 SELECT時にパーティションキーの指定を強制するオプション。
 不特定多数からクエリが発行される場合、指定しておくのがベター。
• クエリミスで課金額が増加することを防ぐ目的。
 特殊なオペレーションが発生する場合はALTER TABLEで後から変更もできる。
ALTER TABLE mydataset.mytable
SET OPTIONS (
-- 5日後のパーティションが00:00:00 UTCで削除される。
partition_expiration_days = 5);
ALTER TABLE mydataset.mypartitionedtable
SET OPTIONS (
-- パーティションキーをwhere句に入れないとstatementエラーとなる
require_partition_filter = true);
- 11 -
データセット(思案中)
 BigQueryではテーブルをまとめる粒度をデータセットという。
 設計パターンは2択があり得るが、どちらが良いかは未だに悩む..
Design
全テーブルを同
一データセット
に投入する
用途別に
データセットを
分ける
 個人情報あり・なし、組織ごとなどでデータ
セットを分けるパターン。
 権限の考え方が明確になるので、後々こ
ちらのほうが良いと判断して採用。
 ただし、どのテーブルがどのデータセットに属
するのか設計時に検討しておく必要あり。
 BQでは各クエリでデータセットを指定する
必要があるので、後からデータセットを変更
しにくい。
 全テーブルを同一のデータセットに入れてし
まうパターン。
 テーブル設計時点ではデータセット設計が
不要となる。
 テーブル粒度で権限をつけることも可能な
のでちゃんと管理できればこちらでも問題無
さそう。
 ただし、権限設定を各テーブルで設定する
必要があるので抜け漏れリスクが増える。
 何かしらの手段で機械的に管理できれば
こちらの方式が優位になりそう。
- 12 -
データモデリングツール
 BigQuery標準となるモデリングツールは存在しない。
 ので、柔軟にデータモデル定義ができるA5:SQL Mk-2を採用。
 ARRAY<STRUCT>を使用しないテーブルでは定義からDDLを生成、そのまま使用できる。
Design
create table sample_dataset.sample_table (
string_item STRING not null
, int_item INT64 not null
, date_item DATE
, datetime_item DATETIME
, array_item ARRAY<STRING>
, cre_tran_id STRING not null
, cre_dt DATETIME not null
, cre_func_id STRING not null
, upd_tran_id STRING
, upd_dt DATETIME
, upd_func_id STRING
, patch_dt DATETIME
, patch_user_id STRING
) PARTITION BY date_item
OPTIONS(
partition_expiration_days = 5
, require_partition_filter=true
)
;
物理名にデータセット.テーブル名を
指定
CREATE TBLEオプションでパーティシ
ョンキーやその他オプションを指定
型はフリーテキストで記載できるので、
SQL標準外の型にも対応できる。
- 13 -
Implements
- 14 -
ARRAYとの付き合い方
BQ推奨&便利だけどハマりどころもあり
Implements
- 15 -
ARRAYとの付き合い方
 ポイント1: NULLの概念が存在しない。
Implements
!?
- 16 -
ARRAYとの付き合い方
 ポイント1: NULLの概念が存在しない。
Implements
よく見ると..
内部的には空配列で格納されている。
BQコンソール上nullと表記されている
だけ
- 17 -
ARRAYとの付き合い方
 ポイント1: NULLの概念が存在しない。
Implements
正しくはarray_lengthで配列長を判定する必要がある。
- 18 -
ARRAYとの付き合い方
 ポイント2:UNNESTによる展開は行落ちの可能性がある
Implements
当然3行取得できる。
- 19 -
ARRAYとの付き合い方
 ポイント2:UNNESTによる展開は行落ちの可能性がある
Implements
当然3行取得できる。
- 20 -
ARRAYとの付き合い方
 ポイント2:UNNESTによる展開は行落ちの可能性がある
Implements
よく見る記法でunnestすると、空配列
が格納されている行が落ちる。
- 21 -
ARRAYとの付き合い方
 ポイント2:UNNESTによる展開は行落ちの可能性がある
Implements
行落ちさせないためにはleft outer
joinを明記する必要がある。
ちなみに、前ページの記載方法は
inner joinと等価
- 22 -
DDL/DML/DCL
 RDBで使用するDDL/DML/DCLはほぼすべて対応している。
 create/drop/alter
 insert/update/delete/truncate/merge
 grant/revoke
 が、一部例外あり。カラムの型変更に対応していない。
 カラム名の変更、同種の緩い桁数/精度への変更には対応している。
Implements
-- INT64 → NUMERICへの変更
CREATE TABLE dataset.table(c1 INT64);
ALTER TABLE dataset.table ALTER COLUMN c1 SET DATA TYPE NUMERIC;
-- 精度を緩める変更
CREATE TABLE dataset.table (pt NUMERIC(7,2));
ALTER TABLE dataset.table ALTER COLUMN pt SET DATA TYPE NUMERIC(8,2);
-- カラム名の変更(2022.9時点でプレビュー)
ALTER TABLE mydataset.mytable RENAME COLUMN A TO columnA
-- 精度をきつくする変更
CREATE TABLE dataset.table (pt NUMERIC(8,2));
ALTER TABLE dataset.table ALTER COLUMN pt SET DATA TYPE NUMERIC(7,2);
-- 異種データ型への変更
CREATE TABLE dataset.table(c1 INT64);
ALTER TABLE dataset.table ALTER COLUMN c1 SET DATA TYPE STRING;
OKパターン NGパターン
- 23 -
暗号化/復号化
 カラムレベルの暗号化/復号化を行いたい場合はAEAD暗号化関数が使用できる。
 SQL関数ライクにAES暗号化/復号化処理を実装可能。
 共通鍵はGCSに配置することでセキュアな運用が可能。
Implements
暗号化
SELECT
AEAD.ENCRYPT(KEYS.KEYSET_CHAIN(kms_resourc
e_name, keyset_bytes), ‘暗号化対象文字列’,
additional_keyword)
SELECT
AEAD.DECRYPT_STRING(KEYS.KEYSET_CHAIN(kms_
resource_name, keyset_bytes), ‘復号化対象
BYTE配列’, additional_keyword)
復号化
- 24 -
Test
- 25 -
2つの観点 Tests
どうCIを回すか?
単体テストを
どう実装するか?
- 26 -
単体テストをどう実装するか?
4つのアプローチ
Tests
User
Define
Function
Insert
select
Table
Function
SQL
Dryrun
 BQではSQLのドライランが可能
 実行が難しいクエリも構文チェッ
クは可能。
 複雑なデータ加工や分析関
数をUserDefineFunction
に切り出していく。
 テストはBQクライアントが存在
するプログラミング言語であれ
ば比較的簡単に実装可能。
 TableFunctionでモックデータ
の投入、assert文でテストケー
スを書く。
 SQLのみで単体テストの実装
が可能。
 テーブル関数の実装がやや特
殊であり慣れが必要。
 またテーブル関数変更はDDLと
なるので、処理変更で
REPLACEが必要。
 事前データを容易、SQL実行後
にselect結果を検証する。(古き
良きテストコード)
 DBUnitに近いアプローチ。
 Insert文とselect文のみでテスト
ができるので、トランザクションによ
るテストが可能。(テストが並列
実行されても問題ない)
 ただし、ARRAY<STRUCT>が
存在するとCSVやEXCELではデ
ータ準備困難。JSONで容易する
必要あり。
- 27 -
どうCI環境を作るか?
 CIツールは置いておいて、大まかに方式は2択
Tests
 Docker Imageでテスト環境を作る方式。
 昨今のCIツール(
CircleCI/GitlabCI/GithubActions etc
)であれば対応している。
 テストが並列実行されても競合することがな
いので、可能であればこの方式が良い。
 が、残念ながら2022.9月時点でBQの
mockイメージが存在しなく、採用不可。
 巷のツールもBQ構文に対応していなく、同じ
く採用不可。
 実物のBigQueryを使用する方式。
 テスト用のGCPプロジェクトが必要。
 1つのプロジェクトだとテストが並列実行され
た場合に競合してしまう可能性あり。(
DDLはトランザクション対象外のため)
 Docker方式が採用できないため、こちらの
方式を採用。
 テスト程度のデータ量であればどれだけ回して
もほぼ料金がかからないため、テスト用に複
数プロジェクトを作成しても問題無し。
- 28 -
Thank you for listening

FutureTechNight_GoogleCloudデータ活用勉強会.pptx

  • 1.
    - 0 - FutureTech Night Google Cloud データ活用勉強会 2022/9/22 Shota Miyazaki
  • 2.
    - 1 - Profile Name:宮崎 将太 In: Technology Innovation Group (TIG) / DX Unit Post: Architect Specialty: Server Side Like: Data Modeling, Dev Design, Beer🍺 Career: 小売 ポータル サイト ガス基幹 システム 大手小売 基幹 システム 小田急 IDプラット フォーム 大手鉄道 ToC サービス 某安否 サービス 大手企業 データ 基盤 The Go gopher was designed by Renée French
  • 3.
    - 2 - データ基盤アーキテクチャ Cloud Composer Cloud DataFusion BigQeury External System SFTP HTTPS Workflow management DataPipline DWH call data load exec SQL
  • 4.
    - 3 - データ基盤アーキテクチャ Cloud Composer Cloud DataFusion BigQeury External System SFTP HTTPS Workflow management DataPipline DWH call data load exec SQL
  • 5.
  • 6.
  • 7.
    - 6 - BigQueryは列指向データベースDesign Product Quantity Warehaouse dryer 30 Warehouse 2 microwave 20 Warehouse 1 dishwasher 10 null … … … Product dryer microwave dishwasher … Quantity 30 20 10 … Warehaouse Warehouse 2 Warehouse 1 null … 列指向データベース 行指向データベース  RDBは行指向データベース  行ごとにデータが格納される。  レコードを効率的に探索できるが、レコードアクセスのた びに全フィールドを読み取ってしまうため、大量レコード の分析では効率が低下してしまう。  DWHの多くは列指向データベース。BQもこちら。  列ごとにデータが格納される。  列を指定した大量レコード分析で高パフォーマンスを 発揮する。  行の全フィールドを読み出そうとするとパフォーマンスが 低下してしまうので、select * は厳禁。
  • 8.
    - 7 - BQテーブル設計の基本は非正規化 テーブル同士を結合してデータ抽出するより、単一テーブルに対してデータ抽出を行う方がパフォーマンスが良い  粒度が異なるテーブルを非正規化する場合は、ARRAY型やSTRUCT型を利用して非正規化  ただし、ARRAYやSTRUCTを使いすぎるとデータ準備がとても大変…。使用は最小限に。 Design ID 合計金額 1 1,100 2 500 BQでの設計 RDBでのテーブル設計 注文ID 商品 単価 数量 1 商品A 100 3 1 商品B 200 4 2 商品A 100 2 2 商品C 300 1 注文ID 合計金額 注文明細 注文ID 商品 単価 数量 1 1,100 1 商品A 100 3 1 商品B 200 4 2 500 2 商品A 100 2 2 商品C 300 1 注文 注文明細 注文 Select 注文.合計金額 , 注文明細.商品 … From 注文 Inner join ← 正規化テーブルを結合して抽出 注文明細 On 注文.ID = 注文明細.注文ID Select 注文.合計金額 , 注文.注文明細 From 注文 ← 単一テーブルのみへアクセス 粒度ごとにテーブルを正規化 する 注文明細をARRAY<STRUCT>型 として定義する。
  • 9.
    - 8 - 非正規化項目へのアクセス ARRAY項目へのアクセスにはUNNEST関数を使用する。  ただし、UNNESTは曲者(後述) Design 注文ID 合計金額 注文明細 注文ID 商品 単価 数量 1 1,100 1 商品A 100 3 1 商品B 200 4 2 500 2 商品A 100 2 2 商品C 300 1 Select 注文.合計金額 , 注文.注文明細 From 注文 注文ID 合計金額 注文明細 注文ID 商品 単価 数量 1 1,100 1 商品A 100 3 1 1,100 1 商品B 200 4 2 500 2 商品A 100 2 2 500 2 商品C 300 1 select 注文.合計金額 , 注文明細.注文ID , 注文明細.商品 , 注文明細.単価 from 注文 , unnest(注文明細) as 注文明細 何もしないと2行取れる換算になる。 注文明細の各フィールドにはアクセスでき ない。 UNNESTするとARRAYが展開されて4行 取れる。 注文明細の各フィールドにはアクセ スできる用になる。
  • 10.
    - 9 - パーティショニング Bigqueryでは大まかに3つの方法でパーティショニングが可能。  特に制約がなければ列パーティショニング使用がおすすめ。 Design 列パーティ ショニング テーブル シャーディ ング 取り込み時間 パーティショ ニング  パーティションカラムを指定して日別、 時間別、月別、年別、もしくは指定 した整数範囲でパーティショニングす る方式。  RDBを使用していると最も直感的な パターン。  特に制約がなければ列パーティショニ ング使用がベター。  取り込み時間で自動的にパーティシ ョンを作成する方式。  _PARTITIONTIMEという疑似列 が作成され、パーティションキーとして 採用される。  時間がUTCとなってしまうため、列パ ーティショニングとするのがおすすめ。  [PREFIX]_YYYYMMDD などの 名前の接頭辞を使用して複数のテ ーブルにデータを格納する方式。  パーティショニングというよりもテーブル 分割なので、列パーティショニングや 取り込み時間パーティショニングの方 がパフォーマンス高。  GoogleAnalyticsのBQ連携を実施す ると自動的にこの方式になる。
  • 11.
    - 10 - パーティショニングetc  DDLで有効期限を設定可能。  指定した有効期限を超過した場合、自動的に過去パーティションが削除される。  有効期限の境界はUTCとなってしまうことに注意。  有効期限はALTER TABLEで後から変更することも可能なので、リリース後安定期に入ってから改廃を開始する運用も容易。 Design  パーティションフィルタ  SELECT時にパーティションキーの指定を強制するオプション。  不特定多数からクエリが発行される場合、指定しておくのがベター。 • クエリミスで課金額が増加することを防ぐ目的。  特殊なオペレーションが発生する場合はALTER TABLEで後から変更もできる。 ALTER TABLE mydataset.mytable SET OPTIONS ( -- 5日後のパーティションが00:00:00 UTCで削除される。 partition_expiration_days = 5); ALTER TABLE mydataset.mypartitionedtable SET OPTIONS ( -- パーティションキーをwhere句に入れないとstatementエラーとなる require_partition_filter = true);
  • 12.
    - 11 - データセット(思案中) BigQueryではテーブルをまとめる粒度をデータセットという。  設計パターンは2択があり得るが、どちらが良いかは未だに悩む.. Design 全テーブルを同 一データセット に投入する 用途別に データセットを 分ける  個人情報あり・なし、組織ごとなどでデータ セットを分けるパターン。  権限の考え方が明確になるので、後々こ ちらのほうが良いと判断して採用。  ただし、どのテーブルがどのデータセットに属 するのか設計時に検討しておく必要あり。  BQでは各クエリでデータセットを指定する 必要があるので、後からデータセットを変更 しにくい。  全テーブルを同一のデータセットに入れてし まうパターン。  テーブル設計時点ではデータセット設計が 不要となる。  テーブル粒度で権限をつけることも可能な のでちゃんと管理できればこちらでも問題無 さそう。  ただし、権限設定を各テーブルで設定する 必要があるので抜け漏れリスクが増える。  何かしらの手段で機械的に管理できれば こちらの方式が優位になりそう。
  • 13.
    - 12 - データモデリングツール BigQuery標準となるモデリングツールは存在しない。  ので、柔軟にデータモデル定義ができるA5:SQL Mk-2を採用。  ARRAY<STRUCT>を使用しないテーブルでは定義からDDLを生成、そのまま使用できる。 Design create table sample_dataset.sample_table ( string_item STRING not null , int_item INT64 not null , date_item DATE , datetime_item DATETIME , array_item ARRAY<STRING> , cre_tran_id STRING not null , cre_dt DATETIME not null , cre_func_id STRING not null , upd_tran_id STRING , upd_dt DATETIME , upd_func_id STRING , patch_dt DATETIME , patch_user_id STRING ) PARTITION BY date_item OPTIONS( partition_expiration_days = 5 , require_partition_filter=true ) ; 物理名にデータセット.テーブル名を 指定 CREATE TBLEオプションでパーティシ ョンキーやその他オプションを指定 型はフリーテキストで記載できるので、 SQL標準外の型にも対応できる。
  • 14.
  • 15.
  • 16.
    - 15 - ARRAYとの付き合い方 ポイント1: NULLの概念が存在しない。 Implements !?
  • 17.
    - 16 - ARRAYとの付き合い方 ポイント1: NULLの概念が存在しない。 Implements よく見ると.. 内部的には空配列で格納されている。 BQコンソール上nullと表記されている だけ
  • 18.
    - 17 - ARRAYとの付き合い方 ポイント1: NULLの概念が存在しない。 Implements 正しくはarray_lengthで配列長を判定する必要がある。
  • 19.
    - 18 - ARRAYとの付き合い方 ポイント2:UNNESTによる展開は行落ちの可能性がある Implements 当然3行取得できる。
  • 20.
    - 19 - ARRAYとの付き合い方 ポイント2:UNNESTによる展開は行落ちの可能性がある Implements 当然3行取得できる。
  • 21.
    - 20 - ARRAYとの付き合い方 ポイント2:UNNESTによる展開は行落ちの可能性がある Implements よく見る記法でunnestすると、空配列 が格納されている行が落ちる。
  • 22.
    - 21 - ARRAYとの付き合い方 ポイント2:UNNESTによる展開は行落ちの可能性がある Implements 行落ちさせないためにはleft outer joinを明記する必要がある。 ちなみに、前ページの記載方法は inner joinと等価
  • 23.
    - 22 - DDL/DML/DCL RDBで使用するDDL/DML/DCLはほぼすべて対応している。  create/drop/alter  insert/update/delete/truncate/merge  grant/revoke  が、一部例外あり。カラムの型変更に対応していない。  カラム名の変更、同種の緩い桁数/精度への変更には対応している。 Implements -- INT64 → NUMERICへの変更 CREATE TABLE dataset.table(c1 INT64); ALTER TABLE dataset.table ALTER COLUMN c1 SET DATA TYPE NUMERIC; -- 精度を緩める変更 CREATE TABLE dataset.table (pt NUMERIC(7,2)); ALTER TABLE dataset.table ALTER COLUMN pt SET DATA TYPE NUMERIC(8,2); -- カラム名の変更(2022.9時点でプレビュー) ALTER TABLE mydataset.mytable RENAME COLUMN A TO columnA -- 精度をきつくする変更 CREATE TABLE dataset.table (pt NUMERIC(8,2)); ALTER TABLE dataset.table ALTER COLUMN pt SET DATA TYPE NUMERIC(7,2); -- 異種データ型への変更 CREATE TABLE dataset.table(c1 INT64); ALTER TABLE dataset.table ALTER COLUMN c1 SET DATA TYPE STRING; OKパターン NGパターン
  • 24.
    - 23 - 暗号化/復号化 カラムレベルの暗号化/復号化を行いたい場合はAEAD暗号化関数が使用できる。  SQL関数ライクにAES暗号化/復号化処理を実装可能。  共通鍵はGCSに配置することでセキュアな運用が可能。 Implements 暗号化 SELECT AEAD.ENCRYPT(KEYS.KEYSET_CHAIN(kms_resourc e_name, keyset_bytes), ‘暗号化対象文字列’, additional_keyword) SELECT AEAD.DECRYPT_STRING(KEYS.KEYSET_CHAIN(kms_ resource_name, keyset_bytes), ‘復号化対象 BYTE配列’, additional_keyword) 復号化
  • 25.
  • 26.
    - 25 - 2つの観点Tests どうCIを回すか? 単体テストを どう実装するか?
  • 27.
    - 26 - 単体テストをどう実装するか? 4つのアプローチ Tests User Define Function Insert select Table Function SQL Dryrun BQではSQLのドライランが可能  実行が難しいクエリも構文チェッ クは可能。  複雑なデータ加工や分析関 数をUserDefineFunction に切り出していく。  テストはBQクライアントが存在 するプログラミング言語であれ ば比較的簡単に実装可能。  TableFunctionでモックデータ の投入、assert文でテストケー スを書く。  SQLのみで単体テストの実装 が可能。  テーブル関数の実装がやや特 殊であり慣れが必要。  またテーブル関数変更はDDLと なるので、処理変更で REPLACEが必要。  事前データを容易、SQL実行後 にselect結果を検証する。(古き 良きテストコード)  DBUnitに近いアプローチ。  Insert文とselect文のみでテスト ができるので、トランザクションによ るテストが可能。(テストが並列 実行されても問題ない)  ただし、ARRAY<STRUCT>が 存在するとCSVやEXCELではデ ータ準備困難。JSONで容易する 必要あり。
  • 28.
    - 27 - どうCI環境を作るか? CIツールは置いておいて、大まかに方式は2択 Tests  Docker Imageでテスト環境を作る方式。  昨今のCIツール( CircleCI/GitlabCI/GithubActions etc )であれば対応している。  テストが並列実行されても競合することがな いので、可能であればこの方式が良い。  が、残念ながら2022.9月時点でBQの mockイメージが存在しなく、採用不可。  巷のツールもBQ構文に対応していなく、同じ く採用不可。  実物のBigQueryを使用する方式。  テスト用のGCPプロジェクトが必要。  1つのプロジェクトだとテストが並列実行され た場合に競合してしまう可能性あり。( DDLはトランザクション対象外のため)  Docker方式が採用できないため、こちらの 方式を採用。  テスト程度のデータ量であればどれだけ回して もほぼ料金がかからないため、テスト用に複 数プロジェクトを作成しても問題無し。
  • 29.
    - 28 - Thankyou for listening

Editor's Notes

  • #3 どういう会社
  • #4 どういう会社
  • #5 どういう会社
  • #6 どういう会社
  • #8 どういう会社
  • #9 どういう会社
  • #10 どういう会社
  • #11 どういう会社
  • #12 どういう会社
  • #13 どういう会社
  • #14 どういう会社
  • #16 どういう会社
  • #17 どういう会社
  • #18 どういう会社
  • #19 どういう会社
  • #20 どういう会社
  • #21 どういう会社
  • #22 どういう会社
  • #23 どういう会社
  • #24 どういう会社
  • #25 どういう会社
  • #27 どういう会社
  • #28 どういう会社
  • #29 どういう会社