7.4. Debezium PostgreSQL コネクターによるデータ型のマッピング方法

PostgreSQL コネクターは、行が存在するテーブルのように構造化されたイベントで行への変更を表します。イベントには、各列の値のフィールドが含まれます。その値がどのようにイベントで示されるかは、列の PostgreSQL のデータ型によって異なります。以下のセクションでは、PostgreSQL データ型をイベントフィールドの リテラル型 および セマンティック型にマッピングする方法を説明します。

  • リテラル型 は、Kafka Connect スキーマ型を使用して、値をリテラルで表す方法を記述します。INT8INT16INT32INT64FLOAT32FLOAT64BOOLEANSTRINGBYTESARRAYMAP、および STRUCT
  • セマンティック型 は、フィールドの Kafka Connect スキーマの名前を使用して、Kafka Connect スキーマがフィールドの 意味 をキャプチャーする方法を記述します。

詳細は以下を参照してください。

基本型

以下の表は、コネクターによる基本型へのマッピング方法を説明しています。

表7.10 PostgreSQL の基本データ型のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

BOOLEAN

BOOLEAN

該当なし

BIT(1)

BOOLEAN

該当なし

BIT( > 1)

BYTES

io.debezium.data.Bits

length パラメーターには、ビット数を表す整数が含まれます。結果となる byte[] にはビットがリトルエンディアン 形式で含まれ、指定数のビットが含まれるようにサイズが指定されます。例えば、numBytes = n/8 + (n % 8 == 0 ?0 :1) (n はビット数。

BIT VARYING[(M)]

BYTES

io.debezium.data.Bits

length スキーマパラメーターには、ビット数を表す整数が含まれます (列に長さが指定されていない場合は 2^31 - 1)。結果となる byte[] にはビットがリトルエンディアン形式で含まれ、コンテンツに基づいてサイズが指定されます。io.debezium.data.Bits 型の length パラメーターには、指定したサイズ (M) が格納されます。

SMALLINT, SMALLSERIAL

INT16

該当なし

INTEGER, SERIAL

INT32

該当なし

BIGINT, BIGSERIAL, OID

INT64

該当なし

REAL

FLOAT32

該当なし

DOUBLE PRECISION

FLOAT64

該当なし

CHAR[(M)]

STRING

該当なし

VARCHAR[(M)]

STRING

該当なし

CHARACTER[(M)]

STRING

該当なし

CHARACTER VARYING[(M)]

STRING

該当なし

TIMESTAMPTZ, TIMESTAMP WITH TIME ZONE

STRING

io.debezium.time.ZonedTimestamp

タイムゾーン情報を含むタイムスタンプの文字列表現。タイムゾーンは GMT です。

TIMETZ, TIME WITH TIME ZONE

STRING

io.debezium.time.ZonedTime

タイムゾーン情報を含む時間値の文字列表現。タイムゾーンは GMT です。

INTERVAL [P]

INT64

io.debezium.time.MicroDuration
(デフォルト)

日数の月平均に365.25 / 12.0 式を使用した時間間隔の概数 (ミリ秒単位)。

INTERVAL [P]

STRING

io.debezium.time.Interval
(interval.handling.modestring に設定されている場合)

パターン P<years>Y<months>M<days>DT<hours>H<minutes>M<seconds>S に従ったインターバル値の文字列表現。たとえば P1Y2M3DT4H5M6.78S

BYTEA

BYTES または STRING

該当なし

コネクターの バイナリー処理モード 設定に基づいた raw バイト (デフォルト)、base64 でエンコードされた文字列、または 16 進数でエンコードされた文字列。

JSON, JSONB

STRING

io.debezium.data.Json

JSON ドキュメント、配列、またはスケーラーの文字列表現が含まれます。

XML

STRING

io.debezium.data.Xml

XML ドキュメントの文字列表現が含まれます。

UUID

STRING

io.debezium.data.Uuid

PostgreSQL UUID 値の文字列表現が含まれます。

POINT

STRUCT

io.debezium.data.geometry.Point

2 つの FLOAT64 フィールド、(x,y) を持つ構造体を含みます。各フィールドは、描画ポイントの座標を表します。

LTREE

STRING

io.debezium.data.Ltree

PostgreSQL の LTREE 値の文字列表現が含まれます。

CITEXT

STRING

該当なし

INET

STRING

該当なし

INT4RANGE

STRING

該当なし

整数の範囲。

INT8RANGE

STRING

n/a

bigint の範囲。

NUMRANGE

STRING

n/a

numeric の範囲

TSRANGE

STRING

該当なし

タイムゾーンのないタイムスタンプの範囲の文字列表現が含まれます。

TSTZRANGE

STRING

該当なし

ローカルシステムのタイムゾーンが含まれるタイムスタンプの範囲の文字列表現が含まれます。

DATERANGE

STRING

該当なし

日付の範囲の文字列表現が含まれます。上限は常に排他的です。

ENUM

STRING

io.debezium.data.Enum

Postgre SQL のENUM 値の文字列表現を含みます。許可される値のセットは、allowed スキーマパラメーターで維持されます。

Temporal (一時) 型

タイムゾーン情報が含まれる PostgreSQL の TIMESTAMPTZ and TIMETZ データ型以外に、時間型がマッピングされる仕組みは time.precision.mode コネクター設定プロパティーの値によって異なります。ここでは、以下のマッピングについて説明します。

time.precision.mode=adaptive

time.precision.mode プロパティーがデフォルトの adaptive に設定された場合、コネクターは列のデータ型定義に基づいてリテラル型とセマンティック型を決定します。これにより、イベントがデータベースの値を 正確 に表すようになります。

表7.11 time.precision.modeadaptive の場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

DATE

INT32

io.debezium.time.Date

エポックからの日数を表します。

TIME(1), TIME(2), TIME(3)

INT32

io.debezium.time.Time

午前 0 時から経過した時間をミリ秒で表し、タイムゾーン情報は含まれません。

TIME(4), TIME(5), TIME(6)

INT64

io.debezium.time.MicroTime

午前 0 時から経過した時間をマイクロ秒で表し、タイムゾーン情報は含まれません。

TIMESTAMP(1), TIMESTAMP(2), TIMESTAMP(3)

INT64

io.debezium.time.Timestamp

エポックからの経過時間をミリ秒で表し、タイムゾーン情報は含まれません。

TIMESTAMP(4), TIMESTAMP(5), TIMESTAMP(6), TIMESTAMP

INT64

io.debezium.time.MicroTimestamp

エポックからの経過時間をマイクロ秒で表し、タイムゾーン情報は含まれません。

time.precision.mode=adaptive_time_microseconds

time.precision.mode 設定プロパティーが adaptive_time_microseconds に設定されている場合には、コネクターは列のデータ型定義に基づいて一時的な型のリテラル型とセマンティック型を決定します。これにより、マイクロ秒としてキャプチャーされた TIME フィールド以外は、イベントがデータベースの値を 正確 に表すようになります。

表7.12 time.precision.modeadaptive_time_microseconds の場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

DATE

INT32

io.debezium.time.Date

エポックからの日数を表します。

TIME([P])

INT64

io.debezium.time.MicroTime

時間の値をマイクロ秒単位で表し、タイムゾーン情報は含まれません。PostgreSQL では、範囲 が 0 - 6 の精度 P が許可され、マイクロ秒の精度まで保存されます。

TIMESTAMP(1) , TIMESTAMP(2), TIMESTAMP(3)

INT64

io.debezium.time.Timestamp

エポックからの経過時間をミリ秒で表し、タイムゾーン情報は含まれません。

TIMESTAMP(4) , TIMESTAMP(5), TIMESTAMP(6), TIMESTAMP

INT64

io.debezium.time.MicroTimestamp

エポックからの経過時間をマイクロ秒で表し、タイムゾーン情報は含まれません。

time.precision.mode=connect

time.precision.mode 設定プロパティーが connect に設定された場合、コネクターは Kafka Connect の論理型を使用します。これは、コンシューマーが組み込みの Kafka Connect の論理型のみを処理でき、可変精度の時間値を処理できない場合に便利です。ただし、PostgreSQL はマイクロ秒の精度をサポートするため、 connect 時間精度を指定してコネクターによって生成されたイベントは、データベース列の少数秒の精度値が 3 よりも大きい場合に、精度が失われます

表7.13 time.precision.modeconnect の場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

DATE

INT32

org.apache.kafka.connect.data.Date

エポックからの日数を表します。

TIME([P])

INT64

org.apache.kafka.connect.data.Time

午前 0 時からの経過時間をミリ秒で表し、タイムゾーン情報は含まれません。PostgreSQL では、範囲 が 0 - 6 の精度 P が許可され、マイクロ秒の精度まで保存されますが、P が 3 よりも大きい場合は、このモードでは精度が失われます。

TIMESTAMP([P])

INT64

org.apache.kafka.connect.data.Timestamp

エポックからの経過時間をミリ秒で表し、タイムゾーン情報は含まれません。PostgreSQL では、範囲 が 0 - 6 の精度 P が許可され、マイクロ秒の精度まで保存されますが、P が 3 よりも大きい場合は、このモードでは精度が失われます。

TIMESTAMP 型

TIMESTAMP 型は、タイムゾーン情報のないタイムスタンプを表します。このような列は、UTC を基にして同等の Kafka Connect 値に変換されます。例えば、time.precision.modeconnect に設定されていない場合、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 に設定されている場合には コネクターはDECIMALNUMERIC 列すべてに Kafka Connect org.apache.kafka.connect.data.Decimal 論理型を使用します。これはデフォルトのモードです。

表7.14 decimal.handling.modeprecise 場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

NUMERIC[(M[,D])]

BYTES

org.apache.kafka.connect.data.Decimal

scale スキーマパラメーターには、小数点を移動した桁数を表す整数が含まれます。

DECIMAL[(M[,D])]

BYTES

org.apache.kafka.connect.data.Decimal

scale スキーマパラメーターには、小数点を移動した桁数を表す整数が含まれます。

このルールには例外があります。スケーリング制約なしで NUMERIC または DECIMAL 型が使用されると、データベースから取得される値のスケールは値ごとに異なります (可変)。この場合、コネクターは io.debezium.data.Variable Scale Decimal を使用し、これには転送された値とスケールの両方が含まれます。

表7.15 スケーリング制約がない場合の 10 進数型のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

NUMERIC

STRUCT

io.debezium.data.VariableScaleDecimal

転送された値のスケールが含まれる INT32 型の scale と、元の値がスケーリングされていない形式で含まれる BYTES 型の value の 2 つのフィールドがある構造が含まれます。

DECIMAL

STRUCT

io.debezium.data.VariableScaleDecimal

転送された値のスケールが含まれる INT32 型の scale と、元の値がスケーリングされていない形式で含まれる BYTES 型の value の 2 つのフィールドがある構造が含まれます。

decimal.handling.mode プロパティーが double に設定されている場合、コネクターはすべての DECIMAL および NUMERIC 値を Java の double 値として表し、次の表のようにエンコードします。

表7.16 decimal.handling.modedouble の場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名)

NUMERIC[(M[,D])]

FLOAT64

 

DECIMAL[(M[,D])]

FLOAT64

 

decimal.handling.mode 設定プロパティーの最後の設定は string です。この場合、コネクターは DECIMAL および NUMERIC 値をフォーマットされた文字列表現として表し、それらを以下の表のようにエンコードします。

表7.17 decimal.handling.modestring の場合のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名)

NUMERIC[(M[,D])]

STRING

 

DECIMAL[(M[,D])]

STRING

 

Postgre SQL は、decimal.handling.mode の設定が string または double の場合、DECIMAL /NUMERIC 値に格納される特別な値として Na N(not a number) をサポートしています。この場合、コネクターは NaNDouble.NaN または文字列定数 NAN のいずれかとしてエンコードします。

HSTORE 型

dhstore.handling.mode コネクター設定プロパティーが json (デフォルト) に設定されている場合、コネクターは HSTORE 値を JSON 値の文字列表現として表し、以下の表で示すようにエンコードします。hstore.handling.mode プロパティーが map に設定されている場合、コネクターは HSTORE 値に MAP スキーマタイプを使用します。

表7.18 HSTORE データタイプのマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

HSTORE

STRING

io.debezium.data.Json

例: JSON コンバーターを使用した出力表現は {"key" : "val"}

HSTORE

MAP

該当なし

例: JSON コンバーターを使用した出力表現: {"key" : "val"}

ドメイン型

PostgreSQL は、他の基礎となるタイプに基づいたユーザー定義の型をサポートします。このような列型を使用すると、Debezium は完全な型階層に基づいて列の表現を公開します。

重要

PostgreSQL ドメイン型を使用する列で変更をキャプチャーするには、特別に考慮する必要があります。デフォルトデータベース型の 1 つを拡張するドメインタイプと、カスタムの長さまたはスケールを定義するドメインタイプが含まれるように列が定義されると、生成されたスキーマは定義されたその長さとスケールを継承します。

カスタムの長さまたはスケールを定義するドメインタイプを拡張する別のドメインタイプが含まれるように列が定義されていると、その情報は PostgreSQL ドライバーの列メタデータにはないため、生成されたスキーマは定義された長さやスケールを継承 しません

ネットワークアドレス型

PostgreSQL には、IPv4、IPv6、および MAC アドレスを保存できるデータ型があります。ネットワークアドレスの格納には、プレーンテキスト型ではなくこの型を使用することが推奨されます。ネットワークアドレス型は、入力エラーチェックと特化した演算子および関数を提供します。

表7.19 ネットワークアドレス型のマッピング

PostgreSQL のデータ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

INET

STRING

該当なし

IPv4 ネットワークおよび IPv6 ネットワーク

CIDR

STRING

該当なし

IPv4 と IPv6 のホストおよびネットワーク

MACADDR

STRING

該当なし

MAC アドレス

MACADDR8

STRING

該当なし

EUI-64 形式の MAC アドレス

PostGIS タイプ

PostgreSQL コネクターは、すべての PostGIS データ型 をサポートします。

表7.20 PostGIS データ型のマッピング

PostGIS データ型リテラル型 (スキーマ型)セマンティック型 (スキーマ名) および注記

GEOMETRY
(planar)

STRUCT

io.debezium.data.geometry.Geometry

: フィールドが 2 つの構造が含まれます。

  • srid (INT32) - 構造に保存されるジオメトリーオブジェクトの型を定義する、空間参照システム識別子。
  • wkb (BYTES) - Well-Known-Binary 形式でエンコードされたジオメトリーオブジェクトのバイナリー表現。

詳細は、Open Geospatial Consortium Simple Features Access を参照してください。

GEOGRAPHY
(spherical)

STRUCT

io.debezium.data.geometry.Geography

: フィールドが 2 つの構造が含まれます。

  • srid (INT32) - 構造に保存されるジオグラフィーオブジェクトの型を定義する、空間参照システム識別子。
  • wkb (BYTES) - Well-Known-Binary 形式でエンコードされたジオメトリーオブジェクトのバイナリー表現。

詳細は、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
  • 数値型 ((INTFLOATNUMERIC など)
  • テキストタイプ (CHARVARCHARTEXT など)
  • 時間の種類 (DATETIMEINTERVALTIMESTAMPTIMESTAMPTZ)
  • JSON, JSONB, XML
  • UUID

時間型の場合、デフォルト値の解析は Postgre SQL ライブラリーによって提供されることに注意してください。したがって、Postgre SQL で通常サポートされている文字列表現は、コネクターでもサポートされている必要があります。

デフォルト値がインラインで直接指定されるのではなく関数によって生成される場合、コネクターは代わりに、指定されたデータ型の 0 に相当するものをエクスポートします。これらの値は以下の通りです。

  • BOOLEAN では FALSE
  • 数値タイプの場合、適切な精度で 0
  • text/XML タイプの場合は空の文字列
  • JSON タイプの場合は {}
  • 1970-01-01DATETIMESTAMPTIMESTAMPTZ タイプの場合
  • TIME00:00
  • INTERVALEPOCH
  • 00000000-0000-0000-0000-000000000000 (UUID)

現在、このサポートは、関数の明示的な使用にのみ適用されます。たとえば、CURRENT_TIMESTAMP(6) は括弧付きでサポートされていますが、CURRENT_TIMESTAMP はサポートされていません。

重要

デフォルト値の伝搬のサポートは、主に、スキーマのバージョン間の互換性を強制するスキーマレジストリーを持つ Postgre SQL コネクターを使用する際に、スキーマを安全に進化させるために存在します。この主な問題と、異なるプラグインのリフレッシュ動作のために、Kafka スキーマに存在するデフォルト値は、データベーススキーマのデフォルト値と常に同期していることは保証されません。

  • デフォルト値は、あるプラグインがいつ、どのようにインメモリースキーマの更新をトリガーするかによって、Kafka スキーマに遅れて現れることがあります。リフレッシュの間にデフォルトが何度も変更されると、Kafka スキーマに値が現れないか、スキップされることがある。
  • コネクターに処理を待機しているレコードがあるときにスキーマの更新がトリガーされた場合、デフォルト値が Kafka スキーマに早期に表示されることがあります。これは、カラムのメタデータがレプリケーションメッセージに含まれているのではなく、リフレッシュ時にデータベースから読み取られるためです。これは、コネクターが遅れていてリフレッシュが発生した場合や、更新がソースデータベースに書き込まれ続けている間にコネクターが一時的に停止した場合に、コネクターの起動時に発生する可能性があります。

この動作は予想外かもしれませんが、それでも安全です。影響を受けるのはスキーマ定義のみで、メッセージに含まれる実際の値はソースデータベースに書き込まれたものと一貫性を保ちます。