Agile育成ブログ
未来を変える喜びを
未分類

主要なデータ型(データ定義)

1. 文字列型:VARCHAR

最もよく使われる型です。

  • 定義方法: VARCHAR, STRING, TEXT(これらはすべて同じ意味です)。
  • 特徴:
    • 最大サイズ: 16MBまで(非常に大きいです)。
    • ストレージの節約: VARCHAR(100) と指定しても、実際に10文字しか入っていなければ、Snowflakeは10文字分のスペースしか消費しません。そのため、他のDBのように「サイズを小さくして節約する」という工夫はあまり必要ありません。
    • ベストプラクティス: 迷ったら VARCHAR(サイズ指定なし、または最大)で定義して問題ありません。パフォーマンスに影響は出ないよう設計されています。

2. 数値型:NUMBER

整数から小数点までをカバーします。

  • 定義方法: NUMBER(精度, 尺度)
    • 精度 (Precision): 全体の桁数(最大38桁)。
    • 尺度 (Scale): 小数点以下の桁数。
  • 別名: INTEGER, INT, DECIMAL なども使えますが、内部的にはすべて NUMBER として処理されます。
  • FLOAT型: FLOAT, DOUBLE もあります。これらは「近似値」を扱うため、科学計算には向いていますが、お金の計算(1円の誤差も許されない場合)には必ず NUMBER を使いましょう。

3. 日付・時刻型:DATE, TIME, TIMESTAMP

時系列データの分析に欠かせません。

  • DATE: 日付のみ(YYYY-MM-DD)。
  • TIME: 時刻のみ(HH:MI:SS)。
  • TIMESTAMP: 日付 + 時刻。Snowflakeには3種類あります。
    1. TIMESTAMP_NTZ (No Time Zone): タイムゾーンなし。
    2. TIMESTAMP_TZ (With Time Zone): タイムゾーン情報を保持。
    3. TIMESTAMP_LTZ (Local Time Zone): セッション(ユーザー)の現在地に合わせた時間を表示。
  • 注意点: 分析基盤では、混乱を避けるために TIMESTAMP_NTZ(UTC固定など)がよく使われます。

4. 論理型:BOOLEAN

TRUEFALSE の2択です。

  • 特徴: 内部的には TRUE / FALSE ですが、ロード時には 1 / 0'Yes' / 'No' も自動的に解釈してくれます。

5. 半構造化データ型:VARIANT, ARRAY, OBJECT

前回の回答で触れた「魔法の型」シリーズです。

  • VARIANT: 何でも入る(JSONなど)。
  • ARRAY: リスト形式 ["apple", "banana"]
  • OBJECT: キーと値のペア {"color": "red"}
型のカテゴリー推奨される型定義主な用途
テキストVARCHAR名前、住所、説明文(最大16MB)
整数・金額NUMBER(38,0) / NUMBER(18,2)ID、数量、売上単価(正確な数値)
日付DATE生年月日、注文日
日時TIMESTAMP_NTZログ送信時刻、更新日時
JSONVARIANTAPIレスポンス、タグ情報の丸ごと保存

VARIANT型とは?

VARIANT型とは、「どんなデータ型でも格納できる、万能な器」のことです。 通常のテーブル(構造化データ)は「1列目:数値、2列目:日付」と厳密に型を決めますが、VARIANT型はJSON、Avro、ORC、Parquetなどの「半構造化データ」を、そのまま1つの列に丸ごと入れることができます。

なぜVARIANT型がすごいのか?

  • 事前の定義がいらない: JSONの中身にどんなキーがあるか、事前にテーブルを設計しなくてOK。
  • スキーマ・オン・リード: データを入れるとき(ロード)ではなく、使うとき(クエリ)に型を解釈します。
  • 自動最適化: Snowflakeの裏側では、VARIANTの中身を解析して列形式に圧縮してくれるため、検索速度が落ちません。

2. データの「中身」にアクセスする方法(ドット記法)

VARIANT型に入れたデータを取り出すのは驚くほど簡単です。SQLの中でドット(.)コロン(:)を使うだけで、深い階層のデータも一瞬で引っこ抜けます。

実践例:

例えば、src_json という列に以下のようなデータが入っているとします。 {"user": {"id": 123, "name": "Tanaka"}, "items": ["Apple", "Orange"]}

SELECT
    src_json:user.id::NUMBER AS user_id,     -- ドットとコロンで深い階層へ
    src_json:user.name::STRING AS user_name, -- 最後に「::型名」でキャスト
    src_json:items[0]::STRING AS first_item  -- 配列もインデックスで指定可能
FROM raw_data_table;