dbtのmodels定義においてcolumnsは詳細に書くべきなのか


:::note info

こちらは <a href='https://qiita.com/advent-calendar/2023/dena-24-newgrad'>dbt Advent Calendar 2024</a> の22日目の記事になります:snowman:


（昨日の記事の投稿は<a href='https://qiita.com/Take_q3/items/f8366fb288a50de6622b'>こちら。</a>）

:::

# はじめに
24新卒でデータエンジニアとして働き始めました、あおと申します！

自身の携わっているプロジェクトにて、dbtのmodels定義内に`columns`を記載しない方がいいと判断したケースがあり、これをきっかけに **どの場合に記載が推奨されるのか？** をしっかり理解したくなったので今回整理してみました。

# dbt models のcolumnsとは
前提として、dbtのmodels内の`columns`とは『各データモデル内で使用されるカラムに対するメタデータを提供する』フィールドです。
メタデータとしては **『カラムの説明やデータ型、カラムのテスト、ビジネスルールや制約』** などの情報を記載できます。

```yaml
# columns記載の例

version: 2

models:
  - name: hogehoge_table
    description: hogehogeのテーブル
    columns:
      - name: ho_column
        data_type: string
        description: ho用のカラム
        data_tests:
          - not_null
          - dbt_expectations.expect_column_values_to_be_of_type:
              column_type: string
      - name: ge_column
        data_type: int64
        description: ge用のカラム
        data_tests:
          - not_null
          - accepted_values:
              values: [1, 2, 3]
          - dbt_expectations.expect_column_values_to_be_of_type:
              column_type: int64

```


※dbtの基礎が不安な方は以下の資料がおすすめ。

https://speakerdeck.com/shinyaa31/learn-dbt-from-scratch?slide=17


# columnsを書かないという選択肢
columnsの記述は必須ではないため、一部のcolumnsのみの記載やmodels(テーブル)のみの記載でもエラーなく実行はできます。

上記の例のように説明やカラムごとのテストを記載したい場合はcolumnsまで記述しますが、特段column単位でのメタデータ記載の必要性がないのであれば、以下のように記載することもできるわけです。

```yaml
# columns記載をしない例

version: 2

models:
  - name: hogehoge_table
    description: hogehogeのテーブル
```

今回　『dbtのmodels定義においてcolumnsは詳細に書くべきなのか』という問いは、主にこのような **メタデータの記載がない場合** を前提として、それでも記載すべきなのか考えていきます。


# 詳細に書く場合のメリット・デメリット
上記を踏まえた上で、まずはメリット・デメリットを整理していきます。

## 書く場合の『メタデータ記述』以外のメリット
- **コード上の視認性の強化**
    -  `columns`を詳細に記述することで、ymlだけでデータモデルの構造と意図を明確に表現・理解できるようになり、プロジェクト内の他のメンバーや新たに参加するメンバーがモデルを容易に理解できるようになるメリットがあります。
- **dbt docsに記載できる**
    - `dbt`にはドキュメンテーション生成機能があり、`columns`情報を詳細に記載しておくとウェブUIにも表示できるので便利。もしdbt docsを多用しているのであればメリットになります。

## 書く場合に生じるデメリット
- **時間とリソースの消費**
    - `columns`の詳細な記述・メンテには時間と労力が必要となる。特にプロジェクト初期やリソースが限られている状況では、書くことがデメリットとなるケースもあります。
- **過剰な情報によるyml視認性低下**
    - プロジェクトが小規模である場合やカラムが少ない場合、dbt docs以外のeng向け仕様書で明確にスキーマ定義されている場合などは、ymlへの詳細な情報記述は冗長となり、かえってチームの迅速な理解を妨げる可能性があります。
- **変更に対する負荷**
    - カラムが頻繁に変更・追加される場合、全ての変更に対してdl~dmまで`columns`記述を更新するのは手間がかかります。
    - （今回私のチームでcolumns記載を見送ったケースはこれでした。）


# 結論：どういう時にcolumnsを書くべきなのか？
メリットデメリットを整理すると、`columns` を詳細に記述するべきか否かは『プロジェクトの規模、目的、そしてフェーズやチーム状況』によって異なるなという結論になりました。

整理するとざっくり以下になるかなと。

## 書いた方がいいケース
- データモデルが複雑かつ、携わるチームメンバー/新規アサインが多く共有理解が重要な場合
- dbt docsを多用しスキーマ把握をしている場合
- わかりやすい仕様書がない/仕様書も多く複雑でコード上でスキーマが把握しづらい場合

## 書かない方がいいケース
- 小規模プロジェクトでカラムの定義が単純明快な場合
- プロトタイピングや試行錯誤が進行中で、仕様が頻繁に変更される場合
- 他ドキュメントでスキーマが適切に定義されており、ymlでスキーマを詳細に書くことが冗長だと判断される場合
- DMレイヤーなど、DWHの内容をそもままviewとして利用しており既に信頼性を確保している場合

## まとめ
整理し直すと現状の自分のチームの開発状況と照らし合わせることができ、客観的に良し悪し判断できたのでいい経験になりました。

また、私の業務の場合だと書かないケースが多かったのですが、スキーマや仕様書が複雑化してきてる&新規アサインもちらほらある&仕様変更についても[dbt osmosis](https://github.com/z3z1ma/dbt-osmosis)使うとかで労力減らせそうとも思ったので、そろそろymlの整理・dbt docsしっかり使うように導入するのもありなのかな〜と感じました。
(今からdl層〜dm層のyml全て綺麗にし直すとテスト含めとんでもない規模になるので今後のyml記載使用方針固め直すくらいしかできることなさそうですが...😭)

# 参考
https://docs.getdbt.com/reference/model-properties

https://speakerdeck.com/shinyaa31/learn-dbt-from-scratch?slide=17

https://docs.getdbt.com/reference/resource-properties/columns

https://github.com/z3z1ma/dbt-osmosis