7.4. Debezium PostgreSQL コネクターによるデータ型のマッピング方法
PostgreSQL コネクターは、行が存在するテーブルのように構造化されたイベントで行への変更を表します。イベントには、各列の値のフィールドが含まれます。その値がどのようにイベントで示されるかは、列の PostgreSQL のデータ型によって異なります。以下のセクションでは、PostgreSQL データ型をイベントフィールドの リテラル型 および セマンティック型にマッピングする方法を説明します。
-
リテラル型 は、Kafka Connect スキーマ型を使用して、値をリテラルで表す方法を記述します。
INT8
、INT16
、INT32
、INT64
、FLOAT32
、FLOAT64
、BOOLEAN
、STRING
、BYTES
、ARRAY
、MAP
、およびSTRUCT
。 - セマンティック型 は、フィールドの Kafka Connect スキーマの名前を使用して、Kafka Connect スキーマがフィールドの 意味 をキャプチャーする方法を記述します。
詳細は以下を参照してください。
基本型
以下の表は、コネクターによる基本型へのマッピング方法を説明しています。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
| 該当なし |
|
| 該当なし |
|
|
|
|
|
|
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
| 該当なし |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
該当なし |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 該当なし |
|
| 該当なし |
|
|
該当なし |
|
|
n/a |
|
|
n/a |
|
|
該当なし |
|
|
該当なし |
|
|
該当なし |
|
|
|
Temporal (一時) 型
タイムゾーン情報が含まれる PostgreSQL の TIMESTAMPTZ
and TIMETZ
データ型以外に、時間型がマッピングされる仕組みは time.precision.mode
コネクター設定プロパティーの値によって異なります。ここでは、以下のマッピングについて説明します。
time.precision.mode=adaptive
time.precision.mode
プロパティーがデフォルトの adaptive
に設定された場合、コネクターは列のデータ型定義に基づいてリテラル型とセマンティック型を決定します。これにより、イベントがデータベースの値を 正確 に表すようになります。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=adaptive_time_microseconds
time.precision.mode
設定プロパティーが adaptive_time_microseconds
に設定されている場合には、コネクターは列のデータ型定義に基づいて一時的な型のリテラル型とセマンティック型を決定します。これにより、マイクロ秒としてキャプチャーされた TIME
フィールド以外は、イベントがデータベースの値を 正確 に表すようになります。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=connect
time.precision.mode
設定プロパティーが connect
に設定された場合、コネクターは Kafka Connect の論理型を使用します。これは、コンシューマーが組み込みの Kafka Connect の論理型のみを処理でき、可変精度の時間値を処理できない場合に便利です。ただし、PostgreSQL はマイクロ秒の精度をサポートするため、 connect
時間精度を指定してコネクターによって生成されたイベントは、データベース列の少数秒の精度値が 3 よりも大きい場合に、精度が失われます。
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
の値を持つタイムスタンプに変換されます。この動作は、Postgre SQL JDBC ドライバーの標準的な動作を模倣しています。参考として org.postgresql.PGStatement
インタフェースを参照してください。
10 進数型
PostgreSQL コネクター設定プロパティーの設定 decimal.handling.mode
は、コネクターが 10 進数型をマッピングする方法を決定します。
decimal.handling.mode
プロパティーが precise
に設定されている場合には コネクターはDECIMAL
と NUMERIC
列すべてに Kafka Connect org.apache.kafka.connect.data.Decimal
論理型を使用します。これはデフォルトのモードです。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
|
|
|
|
このルールには例外があります。スケーリング制約なしで NUMERIC
または DECIMAL
型が使用されると、データベースから取得される値のスケールは値ごとに異なります (可変)。この場合、コネクターは io.debezium.data.Variable Scale Decimal
を使用し、これには転送された値とスケールの両方が含まれます。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
|
|
|
|
decimal.handling.mode
プロパティーが double
に設定されている場合、コネクターはすべての DECIMAL
および NUMERIC
値を Java の double 値として表し、次の表のようにエンコードします。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) |
---|---|---|
|
| |
|
|
decimal.handling.mode
設定プロパティーの最後の設定は string
です。この場合、コネクターは DECIMAL
および NUMERIC
値をフォーマットされた文字列表現として表し、それらを以下の表のようにエンコードします。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) |
---|---|---|
|
| |
|
|
Postgre SQL は、decimal.handling.mode
の設定が string
または double
の場合、DECIMAL
/NUMERIC
値に格納される特別な値として Na N
(not a number) をサポートしています。この場合、コネクターは NaN
をDouble.NaN
または文字列定数 NAN
のいずれかとしてエンコードします。
HSTORE 型
dhstore.handling.mode
コネクター設定プロパティーが json
(デフォルト) に設定されている場合、コネクターは HSTORE
値を JSON 値の文字列表現として表し、以下の表で示すようにエンコードします。hstore.handling.mode
プロパティーが map
に設定されている場合、コネクターは HSTORE
値に MAP
スキーマタイプを使用します。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
|
|
|
該当なし |
ドメイン型
PostgreSQL は、他の基礎となるタイプに基づいたユーザー定義の型をサポートします。このような列型を使用すると、Debezium は完全な型階層に基づいて列の表現を公開します。
PostgreSQL ドメイン型を使用する列で変更をキャプチャーするには、特別に考慮する必要があります。デフォルトデータベース型の 1 つを拡張するドメインタイプと、カスタムの長さまたはスケールを定義するドメインタイプが含まれるように列が定義されると、生成されたスキーマは定義されたその長さとスケールを継承します。
カスタムの長さまたはスケールを定義するドメインタイプを拡張する別のドメインタイプが含まれるように列が定義されていると、その情報は PostgreSQL ドライバーの列メタデータにはないため、生成されたスキーマは定義された長さやスケールを継承 しません。
ネットワークアドレス型
PostgreSQL には、IPv4、IPv6、および MAC アドレスを保存できるデータ型があります。ネットワークアドレスの格納には、プレーンテキスト型ではなくこの型を使用することが推奨されます。ネットワークアドレス型は、入力エラーチェックと特化した演算子および関数を提供します。
PostgreSQL のデータ型 | リテラル型 (スキーマ型) | セマンティック型 (スキーマ名) および注記 |
---|---|---|
|
|
該当なし |
|
|
該当なし |
|
|
該当なし |
|
|
該当なし |
PostGIS タイプ
PostgreSQL コネクターは、すべての 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-01
DATE
、TIMESTAMP
、TIMESTAMPTZ
タイプの場合 -
TIME
00:00
-
INTERVAL
のEPOCH
-
00000000-0000-0000-0000-000000000000
(UUID
)
現在、このサポートは、関数の明示的な使用にのみ適用されます。たとえば、CURRENT_TIMESTAMP(6)
は括弧付きでサポートされていますが、CURRENT_TIMESTAMP
はサポートされていません。
デフォルト値の伝搬のサポートは、主に、スキーマのバージョン間の互換性を強制するスキーマレジストリーを持つ Postgre SQL コネクターを使用する際に、スキーマを安全に進化させるために存在します。この主な問題と、異なるプラグインのリフレッシュ動作のために、Kafka スキーマに存在するデフォルト値は、データベーススキーマのデフォルト値と常に同期していることは保証されません。
- デフォルト値は、あるプラグインがいつ、どのようにインメモリースキーマの更新をトリガーするかによって、Kafka スキーマに遅れて現れることがあります。リフレッシュの間にデフォルトが何度も変更されると、Kafka スキーマに値が現れないか、スキップされることがある。
- コネクターに処理を待機しているレコードがあるときにスキーマの更新がトリガーされた場合、デフォルト値が Kafka スキーマに早期に表示されることがあります。これは、カラムのメタデータがレプリケーションメッセージに含まれているのではなく、リフレッシュ時にデータベースから読み取られるためです。これは、コネクターが遅れていてリフレッシュが発生した場合や、更新がソースデータベースに書き込まれ続けている間にコネクターが一時的に停止した場合に、コネクターの起動時に発生する可能性があります。
この動作は予想外かもしれませんが、それでも安全です。影響を受けるのはスキーマ定義のみで、メッセージに含まれる実際の値はソースデータベースに書き込まれたものと一貫性を保ちます。