7.4. Debezium PostgreSQL コネクターによるデータ型のマッピング方法
PostgreSQL コネクターは、行が存在するテーブルのように構造化されたイベントで行への変更を表します。イベントには、各列の値のフィールドが含まれます。その値がどのようにイベントで示されるかは、列の PostgreSQL のデータ型によって異なります。以下のセクションでは、PostgreSQL データ型をイベントフィールドの リテラル型 および セマンティック型にマッピングする方法を説明します。
-
literal type は、Kafka Connect スキーマタイプ (
INT8、INT16、INT32、INT64、FLOAT32、FLOAT64、BOOLEAN、STRING、BYTES、ARRAY、MAP、STRUCT) を使用して、値がどのように表現されるかを記述します。 - セマンティック型 は、フィールドの Kafka Connect スキーマの名前を使用して、Kafka Connect スキーマがフィールドの 意味 をキャプチャーする方法を記述します。
デフォルトのデータ型変換がニーズを満たさない場合は、コネクター のカスタムコンバーターを作成 できます。
詳細は以下を参照してください。
基本型
以下の表は、コネクターによる基本型へのマッピング方法を説明しています。
表7.12 PostgreSQL の基本データ型のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
| 該当なし |
|
|
| 該当なし |
|
|
|
|
|
|
|
|
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
| 該当なし |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
該当なし |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 該当なし |
|
|
| 該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
|
時間型
タイムゾーン情報が含まれる PostgreSQL の TIMESTAMPTZ and TIMETZ データ型以外に、時間型がマッピングされる仕組みは time.precision.mode コネクター設定プロパティーの値によって異なります。ここでは、以下のマッピングについて説明します。
time.precision.mode=adaptive
time.precision.mode プロパティーがデフォルトの adaptive に設定された場合、コネクターは列のデータ型定義に基づいてリテラル型とセマンティック型を決定します。これにより、イベントがデータベースの値を 正確 に表すようになります。
表7.13 time.precision.mode が adaptive の場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=adaptive_time_microseconds
time.precision.mode 設定プロパティーが adaptive_time_microseconds に設定されている場合には、コネクターは列のデータ型定義に基づいて一時的な型のリテラル型とセマンティック型を決定します。これにより、マイクロ秒としてキャプチャーされた TIME フィールド以外は、イベントがデータベースの値を 正確 に表すようになります。
表7.14 time.precision.mode が adaptive_time_microseconds の場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=connect
time.precision.mode 設定プロパティーが connect に設定された場合、コネクターは Kafka Connect の論理型を使用します。これは、コンシューマーが組み込みの Kafka Connect の論理型のみを処理でき、可変精度の時間値を処理できない場合に便利です。ただし、PostgreSQL はマイクロ秒の精度をサポートするため、 connect 時間精度を指定してコネクターによって生成されたイベントは、データベース列の少数秒の精度値が 3 よりも大きい場合に、精度が失われます。
表7.15 time.precision.mode がconnect の場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
TIMESTAMP 型
TIMESTAMP 型は、タイムゾーン情報のないタイムスタンプを表します。このような列は、UTC を基にして同等の Kafka Connect 値に変換されます。例えば、time.precision.mode がconnect に設定されていない場合、TIMESTAMP 値 2018-06-20 15:13:16.945104 は、io.debezium.time.Micro Timestamp の値 1529507596945104 で表されます。
Kafka Connect および Debezium を実行している JVM のタイムゾーンは、この変換には影響しません。
Postgre SQL は TIMESTAMP 列に +/-infinite の値を使用することをサポートしています。これらの特殊な値は、正の無限大の場合は9223372036825200000、負の無限大の場合は-9223372036832400000 の値を持つタイムスタンプに変換されます。この動作は、PostgreSQL JDBC ドライバーの標準的な動作に似ています。詳細は、org.postgresql.PGStatement インターフェイスを参照してください。
10 進数型
PostgreSQL コネクター設定プロパティーの設定 decimal.handling.mode は、コネクターが 10 進数型をマッピングする方法を決定します。
decimal.handling.mode プロパティーが precise に設定されている場合には コネクターはDECIMAL と NUMERIC、MONEY 列すべてに Kafka Connect org.apache.kafka.connect.data.Decimal 論理型を使用します。これはデフォルトのモードです。
表7.16 decimal.handling.mode が precise 場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
このルールには例外があります。スケーリング制約なしで NUMERIC または DECIMAL 型が使用されると、データベースから取得される値のスケールは値ごとに異なります (可変)。この場合、コネクターは io.debezium.data.Variable Scale Decimal を使用し、これには転送された値とスケールの両方が含まれます。
表7.17 スケーリング制約がない場合の DECIMAL および NUMERIC 型のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
|
decimal.handling.mode プロパティーが double に設定されている場合、コネクターはすべての DECIMAL、NUMERIC、MONEY 値を Java の double 値として表し、次の表のようにエンコードします。
表7.18 decimal.handling.mode が double の場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) |
|---|---|---|
|
|
| |
|
|
| |
|
|
|
decimal.handling.mode 設定プロパティーの最後の設定は string です。この場合、コネクターは DECIMAL、NUMERIC および MONEY 値をフォーマットされた文字列表現として表し、それらを以下の表に示すとおりエンコードします。
表7.19 decimal.handling.mode がstring の場合のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) |
|---|---|---|
|
|
| |
|
|
| |
|
|
|
Postgre SQL は、decimal.handling.mode の設定が string または double の場合、DECIMAL /NUMERIC 値に格納される特別な値として Na N(not a number) をサポートしています。この場合、コネクターは NaN をDouble.NaN または文字列定数 NAN のいずれかとしてエンコードします。
HSTORE 型
PostgreSQL コネクター設定プロパティーの設定 hstore.handling.mode は、コネクターが HSTORE の値をマッピングする方法を決定します。
dhstore.handling.mode コネクター設定プロパティーが json (デフォルト) に設定されている場合、コネクターは HSTORE 値を JSON 値の文字列表現として表し、以下の表で示すようにエンコードします。hstore.handling.mode プロパティーが map に設定されている場合、コネクターは HSTORE 値に MAP スキーマタイプを使用します。
表7.20 HSTORE データタイプのマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
|
|
|
|
該当なし |
ドメイン型
PostgreSQL は、他の基礎となるタイプに基づいたユーザー定義の型をサポートします。このような列型を使用すると、Debezium は完全な型階層に基づいて列の表現を公開します。
PostgreSQL ドメイン型を使用する列で変更をキャプチャーするには、特別に考慮する必要があります。デフォルトデータベース型の 1 つを拡張するドメインタイプと、カスタムの長さまたはスケールを定義するドメインタイプが含まれるように列が定義されると、生成されたスキーマは定義されたその長さとスケールを継承します。
カスタムの長さまたはスケールを定義するドメインタイプを拡張する別のドメインタイプが含まれるように列が定義されていると、その情報は PostgreSQL ドライバーの列メタデータにはないため、生成されたスキーマは定義された長さやスケールを継承 しません。
ネットワークアドレス型
PostgreSQL には、IPv4、IPv6、および MAC アドレスを保存できるデータ型があります。ネットワークアドレスの格納には、プレーンテキスト型ではなくこの型を使用することが推奨されます。ネットワークアドレス型は、入力エラーチェックと特化した演算子および関数を提供します。
表7.21 ネットワークアドレス型のマッピング
| PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
|
|
|
該当なし |
PostGIS タイプ
PostgreSQL コネクターは、すべての PostGIS データ型 をサポートします。
表7.22 PostGIS データ型のマッピング
| PostGIS データ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
|---|---|---|
|
|
|
詳細は、Open Geospatial Consortium Simple Features Access を参照してください。 |
|
|
|
詳細は、Open Geospatial Consortium Simple Features Access を参照してください。 |
TOAST 化された値
PostgreSQL ではページサイズにハード制限があります。つまり、約 8KB 以上の値は、TOAST ストレージを使って保存する必要があるのです。これは、データベースからのレプリケーションメッセージに影響します。TOAST メカニズムを使用して保存され、変更されていない値は、テーブルのレプリカ ID の一部でない限り、メッセージに含まれません。競合が発生する可能性があるため、Debezium が不足している値を直接データベースから読み取る安全な方法はありません。そのため、Debezium は以下のルールに従って、TOAST 化された値を処理します。
-
REPLICA IDENTITY FULL- TOAST 列の値を持つテーブルは、他の列と同様に変更イベントのbeforeおよびafterフィールドの一部となります。 -
REPLICA IDENTITY DEFAULTのあるテーブル - データベースからUPDATEイベントを受信すると、レプリカ ID の一部ではない変更されていない TOAST 列値はイベントに含まれません。同様に、DELETEイベントを受信するときに TOAST 列 (ある場合) はbeforeフィールドにありません。この場合、Debezium は列値を安全に提供できないため、コネクターはコネクター設定プロパティーunavailable.value.placeholderによって定義されたとおりにプレースホルダー値を返します。
デフォルト値
データベーススキーマのカラムにデフォルト値が指定されている場合、Postgre SQL コネクターは可能な限りこの値を Kafka スキーマに反映させようとします。ほとんどの一般的なデータタイプがサポートされています。
-
BOOLEAN -
数値型 (
(INT、FLOAT、NUMERICなど) -
テキストタイプ (
CHAR、VARCHAR、TEXTなど) -
時間の種類 (
DATE、TIME、INTERVAL、TIMESTAMP、TIMESTAMPTZ) -
JSON,JSONB,XML -
UUID
時間型の場合、デフォルト値の解析は Postgre SQL ライブラリーによって提供されることに注意してください。したがって、Postgre SQL で通常サポートされている文字列表現は、コネクターでもサポートされている必要があります。
デフォルト値がインラインで直接指定されるのではなく関数によって生成される場合、コネクターは代わりに、指定されたデータ型の 0 に相当するものをエクスポートします。これらの値は以下の通りです。
-
BOOLEANではFALSE -
数値タイプの場合、適切な精度で
0 - text/XML タイプの場合は空の文字列
-
JSON タイプの場合は
{} -
1970-01-01DATE、TIMESTAMP、TIMESTAMPTZタイプの場合 -
TIME00:00 -
INTERVALのEPOCH -
00000000-0000-0000-0000-000000000000(UUID)
現在、このサポートは、関数の明示的な使用にのみ適用されます。たとえば、CURRENT_TIMESTAMP(6) は括弧付きでサポートされていますが、CURRENT_TIMESTAMP はサポートされていません。
デフォルト値の伝搬のサポートは、主に、スキーマのバージョン間の互換性を強制するスキーマレジストリーを持つ Postgre SQL コネクターを使用する際に、スキーマを安全に進化させるために存在します。この主な問題と、異なるプラグインのリフレッシュ動作のために、Kafka スキーマに存在するデフォルト値は、データベーススキーマのデフォルト値と常に同期していることは保証されません。
- デフォルト値は、あるプラグインがいつ、どのようにインメモリースキーマの更新をトリガーするかによって、Kafka スキーマに遅れて現れることがあります。リフレッシュの間にデフォルトが何度も変更されると、Kafka スキーマに値が現れないか、スキップされることがある。
- コネクターに処理を待機しているレコードがあるときにスキーマの更新がトリガーされた場合、デフォルト値が Kafka スキーマに早期に表示されることがあります。これは、カラムのメタデータがレプリケーションメッセージに含まれているのではなく、リフレッシュ時にデータベースから読み取られるためです。これは、コネクターが遅れていてリフレッシュが発生した場合や、更新がソースデータベースに書き込まれ続けている間にコネクターが一時的に停止した場合に、コネクターの起動時に発生する可能性があります。
この動作は予想外かもしれませんが、それでも安全です。影響を受けるのはスキーマ定義のみで、メッセージに含まれる実際の値はソースデータベースに書き込まれたものと一貫性を保ちます。