なむなむ

@namb_nam による恥晒し

dbtのベストプラクティスを知る③

前回までの記事 dbtのベストプラクティスを知る① - なむなむ dbtのベストプラクティスを知る② - なむなむ

今回は、ベストプラクティスの中にあった、Git guideを読む。

github.com

Git guide

  • ゴールは2つ
    1. 複数のアナリストがコードベースで作業する際にも一貫性を向上
    2. 必要な決定の数を減らすフレームワークの提供

Git branches

  • Git branchのネーミングルール
    • feature/name-of-feature
    • fix/name-of-fix
    • refactor/name-of-refactor

Commits

  • 命令的なメッセージを持たせるべき
    • "this commit will ..."で始まる以下の内容にする
      • Add MRR models
      • Fix typo in sessions model description
      • Update schema to v2 schema syntax
      • Upgrade project to dbt v0.13.0
  • 早く、頻繁に行う
    • コードの一部でも機能したらすぐコミット
    • 将来的に良くないコードを導入してしまったときに、機能したときの状態に簡単に戻すことができる
  • お好みで、リモートブランチにPushする前にローカルブランチでまとめる(squash)することもできる

Pull requests

  • 作業の機能的なグルーピングをすべき
    • モデル構築と保守作業のような、別々の作業は分けておくべき
  • 本文に、コード変更の背景と、そのコードの機能説明を記載する
    • Trelloへのリンク
    • 導入した新機能を説明するdbt docへのリンク
    • 構築したモデルのDAG画像
    • 関連PRへのリンク(モデル変更のきっかけになったBIツールのアップデートなど)
    • 重大な変更の説明
    • コードマージの手順(フルリフレッシュが必要か、リネームしたモデルを落とすか、など)
    • PRテンプレート(サンプル) を使うことで同じことがしやすくなる
  • レビュー時間を48時間とる
  • 記載者がマージしてよいのは以下の時
    • 少なくともひとりにApproveされる
    • すべてのテストにパスしている
  • 書いたコードをシェアするのに最適な方法なので、コードで協働するのに使える
    • 下書きPRも使える
理解。内容もタイトルもテンプレート化すると後々楽だよな

dbtのベストプラクティスを知る②

前回の記事
dbtのベストプラクティスを知る① - なむなむ

今回は、最後の2章からPro-tipsを学ぶぞ。

Pro-tips for workflows

Use the model selection syntax when running locally

  • 開発中、作業中のモデルと下流のモデルのみ実行するのが良いことがある
  • モデル選択構文を使用する

Run only modified models to test changes ("slim CI")

  • 自信をもってコード変更をマージするには、それによりプロジェクトの他の場所が壊れないか知っておく必要がある
  • そのために、本番データとは別のサンドボックス環境で、gitワークフローの自動チェックとしてテストするのがおすすめ
  • 同時に、プロジェクト内の全モデルをRun・テストするには時間も金もかかる
  • dbtは、以前の本番Runの成果物と比較して、
    • ①変更されたモデルを判断し、変更されていないモデルの上に構築できる
    • ②モデルやテスト結果のステータスを判断できる
      • result:fail, result:error, result:passなど
  • ③賢く再実行するために、スコープ内のモデルでdbtコマンドを手動で上書きするのではなく、result:<status>ステータスを使う
    • ④誤ったモデルをすべて再実行し、同時に行った、誤ったモデルに関連する可能性のある変更も実行し、下流で使用
    • ⑤誤ったモデルをすべて再実行し、再テスト
      また、誤ったモデルに関連する可能性のある変更を同時に実行し、下流で使用
    • 誤ったモデルや失敗したテストをすべて再実行
    • 誤ったモデルをすべて再実行し、同時に行った、誤ったモデルに関連する可能性のある変更を実行し、下流で使用
    • ⑥変更されたノードやエラーノードとは無関係のテストが失敗している(合格するためにデータロードをリフレッシュする必要があるソーステストと考える)
    • 失敗したテストをすべて再実行し、それでも失敗するとわかっているテストは除外
    • "EL"処理中にソースデータが更新され、リフレッシュ後に再実行が必要な場合にも適用できる
# ①
dbt run -s state:modified+ --defer --state path/to/prod/artifacts
dbt test -s state:modified+

# ③
dbt run --select state:modified+ result:error+ --defer --state path/to/prod/artifacts

# ④
dbt build --select state:modified+ result:error+ --defer --state path/to/prod/artifacts

# ⑤
dbt build --select state:modified+ result:error+ result:fail+ --defer --state path/to/prod/artifacts

# ⑥
dbt test --select result:fail --exclude <example test> --defer --state path/to/prod/artifacts

--state target/フラグを使用する場合、result:errorresult:failフラグはdbt buildコマンドを使用する場合のみ同時に(同じコマンドで)選択できます。dbt testは以前のコマンド呼び出しでdbt runからrun_results.jsonを上書きする
stateに関するドキュメント

急に実践的すぎるな???

Pro-tips for dbt Projects

Limit the data processed when in development

  • 開発環境において、実行時間を短縮することで、より迅速にコードを反復可能
  • ターゲット名でデータを制限することで、実行速度を上げる
select
*
from event_tracking.events
{% if target.name == 'dev' %}
where created_at >= dateadd('day', -3, current_date)
{% endif %}

Use hooks to manage privileges on objects that dbt creates

Separate source-centric and business-centric transformations

  • モデリングの2段階
    • ①異なるソースを一貫した構造に変換するソース中心変換
      • 変換の例:カラムの再エイリアスと再キャスト、モデルが正しい粒度を持つための結合・ユニーク化
    • ②ビジネスに関連するエンティティやプロセスを表すモデルへの データ変換や、SQLでビジネス定義を実装するビジネス中心な変換
  • この区別を明確にするために、2種の変換を別のモデルに分けることが最も有効

Managing whitespace generated by Jinja

これも突然だな!  
しかし、意味的なモデル分類は重要そう  
汎用性の高い中間テーブルを作るなどの意味で

dbtのベストプラクティスを知る①

ベストプラクティスから読んで始めるdbt という記事が、とても素晴らしいなと。

  • しっかり公式のdocsを読む
  • 自分なりの感想(得られた事項)を持つ
  • わからないこともメモしておく

同じようにやってみよう。
馬鹿みたいだけど、同じ記事で。
(ついでに英語のリーディングも頑張ろう)

docs.getdbt.com

Best practices

  • ベストプラクティスを見ておくことで、可能な限り効率的になる
  • プロのTipsを実装すればdbtプロジェクトが洗練される

Best practice workflows

Version control your dbt project

  • dbtプロジェクトはヴァージョン管理せよ
    • 新機能・バグ修正のためにGitブランチを切れ
    • マスターブランチにマージする前にコード変更はプルリクでレビューせよ
    • Gitガイド
Gitの説明が丁寧だな... 
過去の状態がわかっていると、何か起きた時にバックアップしやすいか

Use separate development and production environments

  • profileのtargetを使うことで、prod環境とdev環境を分けて管理できる
  • 自分のローカル環境で動かす際はdevに対して、本番環境で動かすときはprodに対してのみ実行すべし
  • about managing environments
自分の作業が本番に影響しないのはいいな
ところでこのdev環境はどこに作られるのかしら

Use a style guide and for your project

ルールの徹底は難しい。揃っていたほうがいいに決まっているが...

Best practices in dbt projects

Use the ref function

  • ref関数はdbtを強力にしているもの
  • ref関数を使えば、
    • dbtは依存関係を推測できる
    • モデルを正しい順序で構築できる
    • 作業している環境の上流のテーブル/ビューから選択することを保証する
  • 他のモデルから選択するときは、直接参照(例:my_schema.my_table)ではなく、ref関数を使え
依存関係が決まっているだけで、更新順序を指定する必要がなくなるのだからすごい

Limit references to raw data

  • dbtプロジェクトはデータベースのローデータに依存する
  • ローデータは通常サードパーティーによってLoad(読み込み)されるので、その構造が時間と共に変化する恐れがある(テーブルやカラムが追加されたり、削除されたり、リネームされたり)
  • これらが起きたとき、ローデータを1箇所でだけ参照していれば、モデルのアップデートは容易
  • ローデータはsourceとして定義するのが推奨される(直接参照するのではなく)
    • そうすればどのモデルにも直接参照がなくなる
つまりローデータを参照するモデル数を減らせ、という意味だな
直接参照を忌避している理由は、依存関係を明らかにしたいからだけ?

Rename and recast fields once

  • ローデータは一般にソースが定義するスキーマ命名規則に従って保存される
    • この構造は、ソースによって異なるし、分析に使いたい命名規則とも異なる場合がある
  • dbtプロジェクトの最初の変換は、以下のルールですべき
    • 1つだけのソースから作る
    • テーブルやカラムは、プロジェクトで使いたいように(ルールに従って)リネームする
    • 正しいデータタイプ(タイムゾーンや通貨)に変換する
  • このモデルを頂点としてすべての後続モデルを作ると、重複するコードを減らすことができる
  • 参考:どのようにdbtプロジェクトを構成するかの意見が書かれた記事
プロジェクトの構成をシンプルにすることが命題なのだな?

Break complex models up into smaller pieces

  • 複数の共通テーブル式(CTE、WITH 句で定義された名前付きサブクエリ)を含むと複雑なモデルになりがち
  • dbtでは別々のモデルに分けることができる
  • 複雑なモデルを分解するのは以下の場合に良い
    • CTEが、2つのモデルで重複している
      • 分割すると下流のモデルがいくつあっても参照できるので、重複コードを減らせる
    • CTEが、選択するデータの粒度を変更する
      • データの粒度(1レコードが表す内容)を変更する変換をテストするのは有用
      • CTEを別のモデルに分割することで、大きなモデルから独立してこの変換をテストできる
    • SQLが多数の行になっている
      • CTEを別のモデルに分割することで、コードを読むときの認知負荷を下げる
とにかく分解せよと。でもモデル数が多すぎると良くないかもな

Group your models in directories

2個目がわからん
ディレクトリには、整理以上の役割があるってことだな?

Add tests to your models

  • dbtには、モデルによって生成された結果についての仮説をテストするためのフレームワークがある
  • プロジェクトにテストを追加することで、以下を保証する
    • SQLが期待通りにデータを変換している
    • ソースデータが期待する値を持っている
  • 最低限、プライマリーキーがユニークかつNULLでないことをテストするのがおすすめ( style guide
複数種類のテスト実装できるの素晴らしい

Consider the information architecture of your data warehouse

  • SQLクライアント経由でデータウェアハウスに接続すると、提示されたデータを理解するためにスキーマ、依存関係、カラムの名前に頼ることがある
  • データウェアハウスの情報アーキテクチャを改善するために、
    • カスタムスキーマを使い、依存関係をロジカルなグルーピングに分解したり、別々のスキーマに中間モデルを隠したりする
      • 一般的に、これらカスタムスキーマはモデルをグルーピングするためのディレクトリと一致し、dbt_project.ymlに記述する
    • stg_などのプレフィックスをつけて、エンドユーザーにクエリ対象を示す
このデータセットに入っているからクエリ対象/非対象、はまだ制御できそうだけど、プレフィックスでできるかな?

Choose your materializations wisely

  • Materialization設定により、モデルの構築方法を決定する
    • Viewは構築が速いが、テーブルに比べるとクエリが遅い
    • インクリメンタルモデルは、テーブルと同等のクエリパフォーマンスで、テーブルより早く構築できるが、プロジェクトが複雑になる
  • 使い分け
    • デフォルトはビュー
    • エンドユーザーに見せなくていい軽い変換はephemeralモデルにする
    • BIツールにクエリされるモデルはテーブルにする
    • 複数モデルに参照されるモデルはテーブルにする
    • テーブルの構築時間が許容範囲を超える場合はインクリメンタルモデルにする
この使い分け、いいな

1%の力(Power of 1%)

『GE 巨人の復活 シリコンバレー式「デジタル製造業」への挑戦』

「規模が大きい会社では、1%の改善が効く」という話としてマネージャーから聞いた。

背景

GEはコングロマリット戦略(自社が保有していない、または直接関係していない他業種の事業を取得する戦略)を採用し多角化していた。
2012年、デジタル化の取り組みを本格化させるにあたり、従業員が30万人の企業で全社デジタル化をいきなり進めるのは難しかったため、初年度はパイロットプロジェクトをいくつか選んで成功事例を作ろうとする「フォーカスとインキュベーション」の年にした。 GEがデジタル化を進めようとしていることは世間にほぼ知られていなかったため、デジタル化の中心になるエンジニアやデータサイエンティストのような人材をなかなか集められない状況で、主催カンファレンス「Minds+Machines」でCEOのイメルトが主張したのが、「1%の力(Power of 1%)」という考え方である。

1%の力(Power of 1%)

GEの産業機器を利用する業界(電力、石油・ガス、航空、鉄道、医療など)では、効率が1%が改善されるだけで膨大な利益が生み出される。
GEの試算では、燃料費を1%改善した時の業界全体・15年累計での利益改善は、航空業界で300億ドル、電力業界で660億ドルになると考えられる。
その1%の改善をもたらすために、産業機器の運用をセンサーデータに基づく改善を進めたい。それを実現するのが「インダストリアルインターネット(ICT技術を活用し、生産性の向上やコストの削減を支援する産業サービス)」である、とした。

この考え方の優れている点

1万円のコストを1%カットしても100円浮くだけだが、1億円のコストを1%カットしたら100万円浮く。
重要なのは100万円カットできることではなく、1%カットできるという点。施策にかかる労力が同じなら、対象が大きければ大きいほど効果が得られる。抜本的ではなく薄くしか効かない施策でも、広範囲に効きそうなら検討の価値ありである。特に、同じ施策が将来的にも効くなら、%の効果はどんどん大きくなる。

データエンジニアリングにおける施策

会社のデータ環境や、自分のデータエンジニアリングにおける1%の改善ってなんだろうか。

データ環境の改善

  • クエリのテンプレートを公開する → クエリを書く時間が短縮される
  • データカタログを充実させる → データを探す時間を短縮する

などはデータ利用のたびに影響する話だから%改善と言えるかもしれない。

製品・サービス・企業の強みを考える

戦略は「1杯のコーヒー」から学べ!』を読んだ。企業戦略とその考え方を紹介した本である。

この書籍の背景にある考え方は、顧客が本当に必要とする価値を創造すること、「バリュープロポジション」である。
バリュープロポジションを作るときに考えるべきは自社らしさであり、顧客起点で考えても差別化できない。

以下、自分に刺さった部分を抽出した。

現状の整理
  • 事業ポートフォリオ
  • 合理化の功罪
    • 強靭な筋力が手に入るとは限らない
    • 行き過ぎた合理化の結果、老人のように痩せ衰える(強みまで手放してしまう)パターンもある
強みの考え方
  • 4つの質問
    • 自分たちならではの強みは何か
    • その強みを必要とする顧客は誰か
    • その顧客は何を必要としているか
    • 顧客が自分たちを選ぶためにはどうすればいいか
  • 考えるヒント
    • 強み≠能力
    • 強み=能力を活かしてどんな価値を顧客に提供するか
    • ターゲットは具体的な『こういう人』まで落とし込めなければ、自分たちらしさの発見・他との差別化もできない
  • 製品を構成する3つのレベル
    • 製品の中核:顧客が本当に買っているもの、提供する価値そのもの
    • 製品の実体:実際に提供されるもの
    • 製品の付随機能:完全な価値を提供するために必要なもの f:id:namb_nam:20211115215838p:plain
企業のあり方
  • 松下幸之助「利益追求が企業の最大命題ではない、利益は社会貢献を成せという社会の声」
    • つまり、事業と社会貢献は同じ

amzn.to


人生の目的がない

レバレッジ時間術』という本を読んだ。お金のように時間も資産と考え、投資のように将来的に使える時間を増やすための方法を紹介していて、一読の価値がある本だと感じた。

課題やタスクに着手する優先度を決める基準の一つとして、「自分たちの作業時間を増やすことができるかどうか」を採用していた上司から、その考え方の根拠としてこの本を紹介してもらった。
「自分たちの作業時間を増やすことができる」というのはつまり、事業への貢献が大きい改善に寄与する時間を増やす、ということだ。そのために、まず、部署外からの問い合わせ対応を減らす取り組みや、定例タスクを簡略化・自動化できるような取り組みを優先するのだ。非常に合理的であると思う。

使える時間を増やすための方法は書籍の中で数多く紹介されているのでぜひ読んで欲しいのだが、そんな工夫や取組みをする理由は、「人生における目的を達成するため」であるとされている。
実は、自分にはそんな大きな目標がなくて困っている。プライベートにおいてもビジネスパーソンとしても、将来的にこうありたいというビジョンが欠落していて、目標から逆算することができない。となるとモチベーションもない。

早く前向きに生きられるようにならねば、と思う。


https://amzn.to/3c8vL5lamzn.to