スキーマ管理
この詳細解説では、Lakeflow Connect の Zerobus Ingest がどのように受信レコードを Delta テーブルスキーマと照合して検証するか、また部分データや進化するデータに対してどのようにスキーマを設計するかを説明します。

テーブルが契約となります
Your Delta table schema is the authoritative contract for what Zerobus Ingest accepts.Zerobus Ingest はその契約に基づいてすべてのレコードをゲートしますが、契約をどれだけ厳格にするか、あるいはどれだけ許容するかはユーザーが選択できます。同じサービスであっても、テーブルの定義方法に応じて、厳格なスキーマを適用したり、柔軟な列のサブセットを受け入れたり、適合しないすべてをキャッチしたりすることができます。
- Zerobus Ingestがデータをゲートします。 すべてのレコードをターゲットテーブルと照らし合わせて検証し、適合しないものはすべて拒否します。推測や列のサイレント削除を行うことはありません。
- コントラクトを定義します。 列を必須または null 許容としてマークし、レスキュー列を追加することで、何が「適合」するかを決定します。
- Zerobus Ingest がテーブルを拡張することはありません。 レコードに対応するために列を追加したり、型を変更したり、スキーマを進化させたりすることはありません。Zerobus Ingest が受け入れる内容は、テーブルを進化させることで進化させます。その逆ではありません。
次のセクションでは、そのコントラクトを形成する 3 つの方法を、最も許容度の高いものから厳格なもの、包括的なものまで順に示します。
レコードがテーブルに照合される仕組み
レコードは宛先テーブルに適合する必要があります。つまり、テーブル内のすべての null 非許容列を最低限含んでいる必要があります。テーブルで null 値を許容する列はレコードから省略でき、NULL として書き込まれます。null 値を許容する列の省略は破壊的でない変更として扱われるため、テーブルに null 値を許容する列を追加しても、それらを含まない古いレコードの取り込みを継続できます。
レコードがテーブルに適合しない場合、Zerobus Ingest はエラーを返します。これには以下が含まれます。
- NULL 非許容の列が不足しています。
- Delta テーブルに存在しない列名(レスキュー列を設定している場合を除く)。
- Delta テーブルと互換性のない型の列。サポートされている Delta および Protobuf データ型については、サポートされているデータ型を参照してください。
コントラクトを形成する3つの方法
テーブルをどのように定義するかによって、取り込みの厳格さや許容度が決まります。以下の3つのシナリオは、最も許容度が高いものから、厳格なもの、すべてを網羅するものへと順に並んでいます。
シナリオ 1: すべての列がオプション(サブセットを受け入れる)
すべての列をNULL可にします。プロデューサーは列の任意のサブセットを送信でき、省略された列は NULL として書き込まれます。テーブルに存在しない列を含むレコードは、引き続き拒否されます。
CREATE TABLE main.default.air_quality (
device_name STRING,
temp INT,
humidity INT);
{"device_name": "sensor-1", "temp": 22, "humidity": 55}: 承認されました。 すべての列が存在します。{"device_name": "sensor-1"}: 承認済み。tempとhumidityは NULL 可であるため、NULLと記述されます。{"device_name": "sensor-1", "temp": 22, "region": "us-west"}: 却下されました。regionはテーブル内に存在しません。
シナリオ 2: 必須列 (特定のフィールドを強制)
列 NOT NULL をマークして必須にします。すべてのレコードでそれらの列を提供する必要があります。そうでない場合は拒否されます。これはスペクトルの厳格な端にあたります。フィールドが常に存在する必要がある場合に使用してください。
CREATE TABLE main.default.air_quality (
device_name STRING NOT NULL,
temp INT NOT NULL,
humidity INT);
{"device_name": "sensor-1", "temp": 22, "humidity": 55}: 承認されました。 必要な列はすべて存在します。{"device_name": "sensor-1", "temp": 22}: 承認済み。humidityは NULL 可であるため、NULLとして書き込まれます。{"device_name": "sensor-1"}: 却下されました。tempは NULL 非許容ですが、欠落しています。
シナリオ 3: レスキュー列(その他すべてをキャッチ)
レコードを拒否する代わりに、スキーマに適合しないフィールドをキャプチャするための VARIANT レスキュー列を追加します。テーブルに一致するフィールドは、通常どおりそれぞれの列に書き込まれます。余分なフィールドや準拠していないフィールドは、JSON オブジェクトとしてレスキュー列にグループ化されます。これは最も許容範囲が広い設定です。余分なフィールドや null 許容列の型の不一致は、拒否されるのではなくキャプチャされます。必須(null 非許容)列が省略されている場合、レスキュー列はスキーマが必要とする値を提供できないため、レコードは引き続き拒否されます。レスキュー列は Beta 版であり、現在は JSON 形式の取り込みをサポートしています。
{"device_name": "sensor-1", "temp": 22, "region": "us-west"}: 承認されました。regionはテーブルに存在しないため、拒否される代わりにレスキュー列にキャプチャされます。
レスキュー列の設定方法と正確なルールについては、Zerobus レスキュー列を参照してください。
スキーマ進化
Zerobus Ingest は、ターゲットテーブルを自動的に進化させません。データの形状が変更された場合は、最初にテーブルを進化させ(例:ALTER TABLEを使用)、その後新しいスキーマに対してレコードを送信してください。
null 値を許容する列の追加は破壊的でない変更です。新しい列を送信しない既存のプロデューサーはそのまま動作し続け、そのレコードには NULL が設定されます。これにより、スキーマの変更とプロデューサーの変更を個別にロールアウトできます。
Protobufスキーマ
Protocol Buffers (protobuf) を使用して取り込む場合、protobuf メッセージ定義にも同じ適合ルールが適用されます。つまり、Delta テーブル内のすべての null 非許容列を最低限含める必要があり、null 許容列は省略可能です。
以下は、protobuf スキーマにも適用されます。
- Zerobus Ingest は、2000 列を超える proto スキーマをサポートしていません。
- Zerobus Ingest は、ASCII 文字、数字、アンダースコアを使用したテーブル名と列名のみをサポートしています。
- Zerobus Ingest は、「ストリーム作成」および「レコード取り込み」操作で異なる proto スキーマを使用することをサポートしていません。