Databricks Certified Data Engineer Associate 教科書
第2章 データ取り込みとロード(Data Ingestion and Loading, 21%)
🎯 この節の学習目標
2-1 から 2-5 で個々の取り込み手段を学びました。本節ではそれらを「どう選ぶか」の視点で総まとめします。判断軸は次の4つです。
| 判断軸 | 問うこと | 効いてくる選択 |
|---|---|---|
| データ量 | ファイル数・行数はどの規模か。今後増えるか | 数千ファイルまでなら COPY INTO、それ以上・増加傾向なら Auto Loader |
| 頻度 | 1回きりか、定期か、継続的か | 1回きり→アップロード UI や CTAS、定期→スケジュール実行、継続→ストリーミング |
| データタイプ / ソース | ファイルか、SaaS か、DB か、API か。構造化か半構造化か | ファイル→COPY INTO / Auto Loader、SaaS・DB→マネージドコネクタ、API→自前 REST |
| ガバナンス要件 | 権限・監査・リネージをどこまで統合したいか | いずれの方式でも宛先は UC 管理テーブル。接続・認証情報も UC / シークレットで管理 |
ソース種別ごとに「まず何を検討するか」を優先順位つきでまとめます。試験のシナリオ問題は、ほぼこの表のどこかに着地します。
| ソース / 状況 | 第1候補 | 第2候補 | 備考 |
|---|---|---|---|
| クラウドストレージ:大規模・継続的・スキーマ進化あり | Auto Loader | Lakeflow Connect 標準コネクタ | チェックポイントで増分管理、file notification で大規模化に対応 |
| クラウドストレージ:数千ファイル・SQL 中心・定時バッチ | COPY INTO | Auto Loader(availableNow) | SQL だけで完結。冪等でリトライ安全 |
| SaaS アプリケーション | Lakeflow Connect マネージドコネクタ | パートナーコネクタ | どちらも未対応なら REST 自前実装 |
| リレーショナルデータベース | Lakeflow Connect マネージドコネクタ | JDBC 自前実装 | JDBC の場合は watermark 列で増分抽出を自作 |
| メッセージバス(Apache Kafka・Amazon Kinesis 等)からのストリーミング | Lakeflow Connect 標準コネクタ(Structured Streaming で自分で構成) | — | 低遅延の継続取り込み。マネージドコネクタの対象外 |
| REST API のみ提供のソース | requests + createDataFrame | — | Lakeflow Jobs でスケジュール。シークレットで認証管理 |
| 手元のファイルを1回だけ | アップロード UI(ファイルのアップロード) | — | 小規模・アドホック専用。運用パイプラインには使わない |
| 手元に繰り返し届くファイル | Unity Catalog Volume + COPY INTO / Auto Loader | — | Volume に置けばストレージ経由と同じ増分取り込みに乗る(2-1) |
図:取り込み方式の選択フロー
📝 試験のポイント
シナリオ問題では、問題文の中のキーワードが方式を指し示します。「SQL のみ」「数千ファイル」→ COPY INTO。「数百万ファイル」「継続的に到着」「スキーマが変わる」→ Auto Loader。「SaaS」「コードを書かずに」「フルマネージド」→ マネージドコネクタ。「Kafka」「メッセージバス」「低遅延ストリーミング」→ 標準コネクタ(Structured Streaming)。「手元のファイルを1回だけ」→ アップロード UI、「手元に繰り返し届く」→ Volume + COPY INTO / Auto Loader。「コネクタ未対応の DB」→ JDBC。「HTTP API しかない」→ REST 自前実装。この対応表を反射的に引けるようにしておきましょう。
取り込み対象として最も扱いが問われるのが JSON です。JSON は行ごとに項目が異なりうる半構造化データであり、スキーマの決め方が論点になります。
read_files はファイルをサンプリングしてスキーマを推論します。Auto Loader は推論結果を schemaLocation に保存し、以降の実行で一貫させます(2-3)schema hints は「スキーマ全体は推論に任せつつ、特定の列だけ型を指定する」仕組みです。全列のスキーマを書き切る手間なく、重要な列の型だけを固定できます。
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.schemaLocation", schema_path)
.option("cloudFiles.schemaHints", "amount DECIMAL(10,2), event_date DATE")
.load(source_path)
)
JSON のネスト(入れ子)は、Spark では struct 型(名前つきフィールドの束)と array 型(同型要素の並び)の列として表現されます。
💡 具体例:ネストした JSON とテーブル上の表現
-- ソースの JSON(1行)
-- {"order_id": 1001,
-- "customer": {"id": "C-01", "region": "east"},
-- "items": [{"sku": "A-1", "qty": 2}, {"sku": "B-9", "qty": 1}]}
-- 取り込み後のスキーマ
-- order_id BIGINT
-- customer STRUCT<id: STRING, region: STRING>
-- items ARRAY<STRUCT<sku: STRING, qty: BIGINT>>
-- struct のフィールドはドット記法で参照できる
SELECT
order_id,
customer.id AS customer_id,
customer.region AS region,
size(items) AS item_count
FROM main.bronze.orders_json;
customer.id のようにドット記法で struct の中へ入れます。array の要素を行に展開する explode などの本格的なネスト変換は、第3章(データ変換)で扱います。取り込み段階では「ネストのまま Bronze に着地させ、展開は後段で行う」のが基本方針です。
スキーマが頻繁に変わる、あるいは事前に定義しきれない JSON に対しては、VARIANT 型という選択肢もあります。VARIANT は半構造化データをスキーマを固定せずそのまま格納する型で、文字列として保存するより効率的に、パス指定での参照ができます。
-- VARIANT 列として JSON を受ける
CREATE TABLE main.bronze.events_v (
event_id BIGINT,
payload VARIANT
);
-- 文字列から VARIANT への変換と参照
SELECT
parse_json(raw_json) AS payload,
payload:user.id::STRING AS user_id,
payload:metrics.duration_ms::BIGINT AS duration_ms
FROM staging_raw;
「struct / array に推論して受ける」か「VARIANT で受けて後から参照する」かは、スキーマの安定度で選びます。項目構成が安定しているなら推論(+schema hints)、変化が激しい・多様なイベントが混在するなら VARIANT が向きます。
✅ この節のまとめ
cloudFiles.schemaHints)。payload:path::型 のパス記法で参照する。問1. あるチームの要件:「クラウドストレージのランディングゾーンに1日あたり数十万ファイルの JSON が継続的に到着する。ソースの項目は時々増える。増分だけを取り込み、新しい項目にも追随したい。」最も適切な取り込み方式はどれか。
正解:B
「大規模(数十万ファイル/日)・継続的・スキーマが変わる」は Auto Loader を指すキーワードの3点セットです。この規模では COPY INTO のファイル照合コストが問題になるためAは不適です。Cは手動運用でありアドホック用途専用です。Dは誤りで、JDBC はデータベース接続の仕組みであり、オブジェクトストレージには使いません。
問2. 別のチームの要件:「経理部門が使う SaaS 会計アプリケーションのデータを毎晩同期したい。チームは SQL アナリスト中心で、抽出コードの開発・保守は避けたい。対応するマネージドコネクタが提供されている。」最も適切な選択はどれか。
正解:A
「SaaS・コードを書きたくない・対応コネクタあり」はマネージドコネクタの典型シナリオです。Bは技術的には可能ですが、開発・保守を避けたいという明示要件に反します(コネクタ未対応の場合の次善策です)。Cは毎晩の手動作業が発生し論外です。Dは誤りで、Auto Loader のソースはクラウドストレージ上のファイルであり、SaaS を直接指定することはできません。
問3. Auto Loader で JSON を取り込んだところ、金額の列 amount が文字列型として推論されてしまった。スキーマ全体は推論に任せたまま、amount 列だけ DECIMAL(10,2) にしたい。最も適切な方法はどれか。
正解:A
schema hints は「推論に任せつつ特定列だけ型を指定する」ための仕組みで、この要件にちょうど合います。Bでも実現はできますが、全列を書き切る保守負担が生じ「スキーマ全体は推論に任せたい」という要件に反します。Cはスキーマ進化(新列への対応)の設定であり、既存列の型指定とは無関係です。Dは誤りで、ターゲット側の変更はソースの推論結果を変えません(そもそも型の不一致で書き込みに失敗する原因になります)。
問4. 取り込んだテーブルに customer という STRUCT 型の列があり、その中の region フィールドを SELECT で取り出したい。正しい書き方はどれか。
SELECT explode(customer) FROM ordersSELECT customer.region FROM ordersSELECT JOIN customer ON region FROM orders正解:B
struct のフィールドは 列名.フィールド名 のドット記法でそのまま参照できます。Aの explode は array を行に展開する関数で、struct のフィールド参照には使いません(第3章で扱います)。Cは構文として成立しません。Dは誤りで、ネストのまま Bronze に着地させて後からドット記法で参照するのは標準的なやり方です。
問5. イベント種別ごとに項目構成がばらばらで、今後も頻繁に変わる JSON ペイロードを取り込む。スキーマを固定せずに格納し、必要なときにパス指定で値を取り出したい。最も適切な格納方法はどれか。
正解:B
「スキーマを固定できない・変化が激しい・パス参照したい」は VARIANT 型の設計意図そのものです。Aは変更のたびにスキーマ改修が必要になり、目的に反します。Cも動きはしますが、型情報を失い、性能・可読性ともに VARIANT に劣ります(VARIANT は文字列格納より効率的に参照できます)。Dはビジネス要件を満たさない先送りにすぎません。